AWK比较两个单独文件中的两列

时间:2015-12-22 16:23:38

标签: linux bash awk comparison data-analysis

我想比较两个文件,并执行以下操作:如果第一个文件中的第5列等于第二个文件中的第5列,我想从第一个文件中打印整行。那可能吗?我搜索了这个问题,但无法找到解决方案:(

文件由制表符分隔,我尝试过这样的事情:

zcat file1.txt.gz file2.txt.gz | awk -F'\t' 'NR==FNR{a[$5];next}$5 in a {print $0}'

有没有人试图做类似的事情? :)

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:6)

您的脚本没问题,但您需要将每个文件单独提供给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)时为true。

a[$5]将第5列的值添加为数组a的索引。 awk中的数组是关联数组,但通常你不关心关联一个值而只是想做一个很好的集合。这是一个 简洁的方法来收集我们在第5列中看到的所有值 第一个文件。随后的next声明表示要立即获得下一个声明 可用记录而不再查看awk程序中的任何语句。

总结以上内容,此行说“如果您正在读取第一个文件(file2.txt), 将第5列的值保存在名为a的数组中,然后转到记录中 继续使用awk程序的其余部分。“

NR == FNR { a[$5]; next }

希望从上面可以清楚地知道我们可以通过第一行的唯一途径 awk程序是我们正在读取第二个文件(在我们的例子中是file1.txt)。

如果第5列的值作为索引出现,则

$5 in a的计算结果为true a数组。换句话说,file1.txt中的第5个记录都是如此 我们在file2.txt的第5列中看到的一个值。

在awk中,当模式部分评估为true时,伴随的动作是 调用。如果没有给出任何操作,如下所示,将触发默认操作 相反,这只是打印当前记录。因此,只是说 $5 in a,我们告诉awk打印file1.txt中的第5个记录 列也出现在file2.txt中,当然这是给定的要求。

$5 in a