我想比较两个文件并执行如下操作:如果第一个文件中的第 5 列等于第二个文件中的第 5 列,我想打印第一个文件中的整行。那可能吗?我搜索了这个问题,但找不到解决方案:(
文件由制表符分隔,我尝试过这样的操作:
zcat file1.txt.gz file2.txt.gz | awk -F'\t' 'NR==FNR{a[$5];next}$5 in a {print $0}'
有没有人试过做类似的事情? :)
在此先感谢您的帮助!
最佳答案
您的脚本没问题,但您需要将每个文件单独提供给 awk 并以相反的顺序提供。
$ cat file1.txt
a b c d 100
x y z w 200
p q r s 300
1 2 3 4 400
$ cat file2.txt
. . . . 200
. . . . 400
$ awk 'NR==FNR{a[$5];next} $5 in a {print $0}' file2.txt file1.txt
x y z w 200
1 2 3 4 400
编辑:
正如评论中所指出的,上面的通用解决方案可以改进并适应 OP 从压缩的制表符分隔文件开始的情况:
$ awk -F'\t' 'NR==FNR{a[$5];next} $5 in a' <(zcat file2.txt) <(zcat file1.txt)
x y z w 200
1 2 3 4 400
解释:
NR是当前正在处理的记录的编号,FNR是编号
当前记录在其文件中。因此 NR == FNR
只是
当 awk 正在处理给它的第一个文件(在我们的例子中是 file2.txt)时为真。
a[$5]
将第 5 列的值作为索引添加到数组 a
中。 awk 中的数组是关联数组,但通常您并不关心关联一个值,而只想制作一个漂亮的东西集合。这是一个
收集我们在第 5 列中看到的所有值的简洁方法
第一个文件。接下来的 next
语句表示立即获取下一个
可用记录,而无需查看 awk 程序中的任何语句。
总结以上内容,这一行表示“如果您正在读取第一个文件 (file2.txt),
将第 5 列的值保存在名为 a
的数组中,然后继续记录没有
继续 awk 程序的其余部分。”
NR == FNR { a[$5]; next }
希望上面的内容很清楚,我们可以通过第一行的唯一方法 awk 程序是如果我们正在读取第二个文件(在我们的例子中是 file1.txt)。
$5 in a
如果第 5 列的值作为索引出现在 a 中,则计算结果为 true
a
数组。换句话说,file1.txt 中第 5 个记录的每条记录都为真
我们在 file2.txt 的第 5 列中看到的列。
在 awk 中,当模式部分计算为真时,伴随的 Action 是
调用。当没有给出 Action 时,如下所示,触发默认 Action
相反,这是简单地打印当前记录。因此,只要说
$5 in a
,我们告诉 awk 打印 file1.txt 中的所有记录,其第 5 个
列也出现在 file2.txt 中,这当然是给定的要求。
$5 in a
关于linux - AWK 比较两个单独文件中的两列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34420217/