我有两个文件,我需要比较它们的第一列,如果找到匹配项,我想从两个文件中输出相应的值。
类似于此Q,但我想从两个文件中打印列中的一个而不是:How to compare multiple columns in two files and retrieve the corresponding value from another column if match found
File1.txt
adeqY 33.7
AIsLX 65.6
AmuBv 1589.0
aZMIx 84.4
File2.txt
AmuBv foo
iwwlp bar
adeqY hi
qUbJZ bye
输出
hi 33.7
foo 1589.0
我有以下awk
命令,但我只设法从File2打印出第二列匹配项:
awk 'FNR==NR{a[$1]; next} ($1) in a {print $2 a[$2]}' File1.txt File2.txt
a[$2]
不想打印
谢谢。
答案 0 :(得分:1)
请您尝试以下。
label count
0 0.0 7128722
1 1.0 29024
输出如下。
awk 'FNR==NR{a[$1]=$2;next} ($1 in a){print $2,a[$1]}' Input_file1 Input_file2
您尝试遇到的问题: :您在foo 1589.0
hi 33.7
上做的只有一件事情,前提是您的FNR==NR
没有任何价值,只是创建了在数组a[$1]
中建立索引,这就是为什么在读取第二个Input_file时它无法打印任何内容的原因。
答案 1 :(得分:1)
您想要做的实际上是在存储在文本文件中的两个表上有一个INNER JOIN,而Linux join命令就是为此而设计的。
尝试:
.blue
说明:
join -t' ' -1 1 -2 1 -o 2.2,1.2 <(sort file1.txt) <(sort file2.txt)
foo 1589.0
hi 33.7
在左侧文件的第一个字段和右侧文件的第一个字段上联接。-1 1 -2 1
定义您要返回的字段。第二个文件中的第二个字段,然后是第一个文件中的第二个字段。另请参见此博客(ref)。
答案 2 :(得分:0)
这里发生的是,一旦您在最后一个awk语句中打印结果,a[]
数组就不再在范围内,因此为什么第二个值不打印。
也许还有另一种方法awk
,但这是我想出的解决方案:
for each in $(comm -1 -2 <(awk '{print $1 }' file1.txt | sort ) <(awk '{print $1 }' file2.txt | sort) ); do echo $(grep $each file2.txt | awk '{print $2}') $(grep $each file1.txt | awk '{print $2}') ; done;
这将输出:
foo 1589.0
hi 33.7
说明:
comm
命令。comm
的两个“文件”实际上是过程替换的,因此它们首先被排序(comm
需要排序的输入),并且仅显示第一列。-1 -2
的{{1}}参数告诉它仅打印文件中的公共元素(它可以显示第一个文件所独有的元素,第二个文件所独有的元素,或两个文件都具有的共同元素)comm
)中的公共元素,请继续并针对出现的行对每个文件进行grep操作,并使用awk仅显示第二个值。因此,最后,我们需要bash for each
循环,for
,sort
和comm
多次。可能不是最优雅的解决方案,但可以完成工作。
答案 3 :(得分:0)
尝试Perl变体
$ cat eskp1.txt
adeqY 33.7
AIsLX 65.6
AmuBv 1589.0
aZMIx 84.4
$ cat eskp2.txt
AmuBv foo
iwwlp bar
adeqY hi
qUbJZ bye
$ perl -F"\s+" -lane 'BEGIN { %kv=map{split /\s+/ } qx(cat eskp1.txt) } { print "$F[1] $kv{$F[0]}" if $kv{$F[0]} } ' eskp2.txt
foo 1589.0
hi 33.7