如何在 Shell 中比较和打印不同文本文件中的数据。
我已经NAS
使用 捕获了三个不同框的详细信息SSH
,现在我需要将所有三个文本文件合并到一个文件中,然后坐骑名称应该在第一列,如果相同山存在于三个盒子中,那么它应该打印在同一行,如果山仅出现在BOX_B和BOX_C然后坐骑名称应出现在第一列和列中盒子_A应保留空白
我们举两个例子df_BoxA.txt和df_BoxB.txt和df_BoxC.txt
例子:
$cat df_BoxA.txt
/logs/boxA 2G 1.2G 7.7G 62% NAS:/logs/boxA
/data/boxA 2G 1.8G 2.0G 91% NAS:/data/boxA
/apps/boxA 2G 1.4G 5.7G 72% NAS:/apps/boxA
/data/java 1G 67M 9.3G 7% NAS:/data/java
/home/admin 10G 4.6G 54G 46% NAS:/home/admin
/admin/arch 10G 8.3G 19G 83% NAS:/admin/arch
/apps/dist 10G 8.3G 19G 83% NAS:/apps/dist
$cat df_BoxB.txt
/logs/boxA 2G 1.2G 7.7G 62% NAS:/logs/boxB
/data/boxA 2G 1.8G 2.0G 91% NAS:/data/boxB
/apps/boxA 2G 1.4G 5.7G 72% NAS:/apps/boxB
/home/user 40G 29.3G 107G 74% NAS:/home/user1
/data/java 1G 67M 9.3G 7% NAS:/data/java
/home/admin 10G 4.6G 54G 46% NAS:/home/admin
/apps/dist 10G 8.3G 19G 83% NAS:/apps/dist
$cat df_BoxC.txt
/logs/boxA 2G 1.2G 7.7G 62% NAS:/logs/boxC
/data/boxA 2G 1.8G 2.0G 91% NAS:/data/boxC
/apps/boxA 2G 1.4G 5.7G 72% NAS:/apps/boxC
/home/user1 40G 29.3G 107G 74% NAS:/home/user1
/home/admin 10G 4.6G 54G 46% NAS:/home/admin
/admin/arch 10G 8.3G 19G 83% NAS:/admin/arch
/apps/dist 10G 8.3G 19G 83% NAS:/apps/dist
合并所有三个文件后,结果应该是这样的
$cat result.txt
/logs/boxA 2G 1.2G 7.7G 62% NAS:/logs/boxA 2G 1.2G 7.7G 62% NAS:/logs/boxB 2G 1.2G 7.7G 62% NAS:/logs/boxC
/data/boxA 2G 1.8G 2.0G 91% NAS:/data/boxA 2G 1.8G 2.0G 91% NAS:/data/boxB 2G 1.8G 2.0G 91% NAS:/data/boxC
/apps/boxA 2G 1.4G 5.7G 72% NAS:/apps/boxA 2G 1.4G 5.7G 72% NAS:/apps/boxB 2G 1.4G 5.7G 72% NAS:/apps/boxC
/data/java 1G 67M 9.3G 7% NAS:/data/java 1G 67M 9.3G 7% NAS:/data/java
/home/admin 10G 4.6G 54G 46% NAS:/home/admin10G 4.6G 54G 46% NAS:/home/admin 10G 4.6G 54G 46% NAS:/home/admin
/admin/arch 10G 8.3G 19G 83% NAS:/admin/arch 10G 8.3G 19G 83% NAS:/admin/arch
/apps/dist 10G 8.3G 19G 83% NAS:/apps/dist 10G 8.3G 19G 83% NAS:/apps/dist 10G 8.3G 19G 83% NAS:/apps/dist
/home/user 40G 29.3G 107G 74% NAS:/home/user1
/home/user1 40G 29.3G 107G 74% NAS:/home/user1
我尝试过使用pr
组合文件的命令,但不是所需的结果。
也尝试过使用sdiff
但无法得到结果。
我该如何解决这个问题?
答案1
你想要做的事情需要一点编程:
#!/usr/bin/perl
# Program to join files of TAB separated data based on first key
# --J. Ziobro--: 11/2014
use strict;
my $f;
my %allLines;
my $maxColumns = 0;
my $fileNum = 0;
my %keys;
foreach $f (@ARGV) {
die "Could not open $f" unless open( F, $f );
while (<F>) {
chop;
my ( $key, @line ) = split /\t/; # assume tab separate all cols
$maxColumns = ( $maxColumns > @line ) ? $maxColumns : @line;
# allLines is indexed by KEY <tab> FileNumber
$keys{$key} = 1;
$allLines{ $key . "\t" . $fileNum } = join( "\t", @line );
}
$fileNum++;
}
foreach ( keys %keys ) {
print $_;
for ( $f = 0 ; $f < $fileNum ; $f++ ) {
if ( exists $allLines{ $_ . "\t" . $f } ) {
print "\t", $allLines{ $_ . "\t" . $f };
}
else {
print " " x $maxColumns;
}
}
print "\n";
}
再见,//Z\
答案2
我是很确定您正在寻找join
。不幸的是,我对此不太擅长。我知道有一种方法可以让它按照您想要的方式填充字段,但到目前为止我只能将不成对的行打印在行首。join
一次只连接两个文件,因此未配对的行不会显示您想要的位置 - 至少,我思考他们没有。你的问题对我来说有点不清楚 - 抱歉。
无论如何,要使用,join
您必须首先sort
在连接字段- 默认情况下这是第一个,也是我在这里采用的:
for f in file[123]
do sort <<IN >"$f"
$(cat "$f")
IN
done
接下来,正如我所说的,join
一次只能连接两个文件,因此我join
编辑了前两个文件,并通过管道将该输出传输到另一个文件join
以获取第三个文件:
join -a1 -a2 file[12] |
join -a1 -a2 - file3 |
column -t | sort -hk2,2
我还通过管道将其column
再次sort
进行格式化。结果如下:
/data/java 1G 67M 9.3G 7% NAS:/data/java 1G 67M 9.3G 7% NAS:/data/java
/apps/boxA 2G 1.4G 5.7G 72% NAS:/apps/boxA 2G 1.4G 5.7G 72% NAS:/apps/boxB 2G 1.4G 5.7G 72% NAS:/apps/boxC
/data/boxA 2G 1.8G 2.0G 91% NAS:/data/boxA 2G 1.8G 2.0G 91% NAS:/data/boxB 2G 1.8G 2.0G 91% NAS:/data/boxC
/logs/boxA 2G 1.2G 7.7G 62% NAS:/logs/boxA 2G 1.2G 7.7G 62% NAS:/logs/boxB 2G 1.2G 7.7G 62% NAS:/logs/boxC
/admin/arch 10G 8.3G 19G 83% NAS:/admin/arch 10G 8.3G 19G 83% NAS:/admin/arch
/apps/dist 10G 8.3G 19G 83% NAS:/apps/dist 10G 8.3G 19G 83% NAS:/apps/dist 10G 8.3G 19G 83% NAS:/apps/dist
/home/admin 10G 4.6G 54G 46% NAS:/home/admin 10G 4.6G 54G 46% NAS:/home/admin 10G 4.6G 54G 46% NAS:/home/admin
/home/user1 40G 29.3G 107G 74% NAS:/home/user1
/home/user 40G 29.3G 107G 74% NAS:/home/user1