匹配两个文件中的列并修改结果文件

时间:2019-06-24 11:42:12

标签: bash awk

我有两个文件,一个文件有3列,一个文件有4列。他们看起来像这样

文件1:

air 0.1 0.2
soil 0.9 0.7
water 0.4 0.6

文件2:

temp1 0.1 0.2 air
temp2 0.5 0.6 .
temp3 0.6 0.3 water

如果文件2中第4列的值与文件中第1列的值匹配,则输出应为:

temp1 0.1 0.2 air 0.1

即文件2的所有值和文件1的前两列。如果不匹配,则应按原样打印文件2的整行:

所以最终输出是

temp1 0.1 0.2 air 0.1
temp2 0.5 0.6 .
temp3 0.6 0.3 water 0.4

如果这是两个文件中值的正常匹配,则可以使用如下所示:

for i in `cat file 1`; do awk '{if($4=="'$i'") print $0_}'<file2 >>output; done

但是,代码所需要的不只是这个。

任何人都可以帮助我解决此问题。

谢谢

3 个答案:

答案 0 :(得分:4)

这确实看起来像是join的经典用法。 join实用程序用于在特定字段上合并文件(必须对文件进行排序)。此答案不使用awk,如果有问题,请不要使用。

cat <<EOF >file1
air 0.1 0.2
soil 0.9 0.7
water 0.4 0.6
EOF
cat <<EOF >file2
temp1 0.1 0.2 air
temp2 0.5 0.6 .
temp3 0.6 0.3 water
EOF

# separator is space
# join on the first field from first file
# join on the firth field from the second file
# in case the lines are not matched, print the line from second file
# output - first output 4 fields from file 2 and second field from file 2
#          it is the same as 3 fields from file 2 and 2 fields from file 1
join -t' ' -11 -24 -a2 -o 2.1,2.2,2.3,2.4,1.2 file1 file2

将输出:

temp1 0.1 0.2 air 0.1
temp2 0.5 0.6 .
temp3 0.6 0.3 water 0.4

repl上进行了测试。

如果您的输入文件未排序,则需要事先在特定字段上对它们进行排序:

 join -t' ' -11 -24 -a2 -o 2.1,2.2,2.3,2.4,1.2 <(<file1 sort -t' ' -k1) <(<file2 sort -t' ' -k4)

如果未对输入文件进行排序,并且您需要保留文件2的排序顺序,请对文件2中的行编号,将它们连接起来,使用file2中的行号对输出进行排序并删除这些行号:< / p>

 join -t' ' -11 -25 -a2 -o 2.1,2.2,2.3,2.4,2.5,1.2 <(<file1 sort -t' ' -k1) <(<file2 nl -w1 -s' ' | sort -t' ' -k5) | sort -t' ' -k1 | cut -d' ' -f2-

答案 1 :(得分:3)

$ awk 'NR==FNR{a[$1]=$2; next} {print $0 ($4 in a ? OFS a[$4] : "")}' file1 file2
temp1 0.1 0.2 air 0.1
temp2 0.5 0.6 .
temp3 0.6 0.3 water 0.4

答案 2 :(得分:2)

抢救Perl!

#!/usr/bin/perl
use warnings;
use strict;

my %F1;
open my $f1, '<', shift or die $!;
while (<$f1>) {
    my ($id, $value) = split;
    warn "Duplicate entry for $id.\n" if exists $F1{$id};
    $F1{$id} = $value;
}

open my $f2, '<', shift or die $!;
while (<$f2>) {
    my ($val0, $val1, $val2, $id) = split;
    print join ' ', $val0, $val1, $val2, $id,
        $F1{$id} x exists $F1{$id}, "\n";
}

另存为match-cols,以perl match-cols file1 file2运行。

它将文件1中的值存储在哈希图中,然后逐行读取文件2,如果在哈希图中未找到ID,则输出行本身,或者输出该行以及哈希图中存储的信息