我想比较两个文件,并做这样的事情:如果第一个文件中的第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 .换句话说,对于file1.txt中的每个记录都是如此,我们在file2.txt的第5列中看到了第5列的值.
在awk中,当模式部分的计算结果为true时,将调用伴随的操作.如果没有给出操作,如下所示,则会触发默认操作,即只打印当前记录.因此,通过说
$5 in a
,我们告诉awk打印file1.txt中的所有记录,其第5列也出现在file2.txt中,这当然是给定的要求.
$5 in a