将不同文本文件中的数据与 Shell 中的文件进行比较和打印

将不同文本文件中的数据与 Shell 中的文件进行比较和打印

如何在 Shell 中比较和打印不同文本文件中的数据。

我已经NAS使用 捕获了三个不同框的详细信息SSH,现在我需要将所有三个文本文件合并到一个文件中,然后坐骑名称应该在第一列,如果相同存在于三个盒子中,那么它应该打印在同一行,如果仅出现在BOX_BBOX_C然后坐骑名称应出现在第一列和列中盒子_A应保留空白

我们举两个例子df_BoxA.txtdf_BoxB.txtdf_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

相关内容