我有两个文件
文件1包含3个字段
文件2包含4个字段
文件1的行数远小于文件2的行数
我想基于第一个字段使用以下操作比较两个文件
如果文件1的任何行中的第一个字段出现在文件2中行的第一个字段中,则不要为文件2打印该行。
任何建议都会感激不尽。
Input File 1
S13109 3739 31082
S45002 3800 31873
S43722 3313 26638
Input File 2
S13109 3738 31081 0
S13109 3737 31080 0
S00033 3008 29985 0
S00033 3007 29984 0
S00022 4130 31838 0
S00022 4129 31837 0
S00188 3317 27372 0
S45002 3759 31832 0
S45002 3758 31831 0
S45002 3757 31830 0
S43722 3020 26345 0
S43722 3019 26344 0
S00371 3737 33636 0
S00371 3736 33635 0
Desired Output
S00033 3008 29985 0
S00033 3007 29984 0
S00022 4130 31838 0
S00022 4129 31837 0
S00188 3317 27372 0
S00371 3737 33636 0
S00371 3736 33635 0
答案 0 :(得分:6)
awk 'FNR==NR{a[$1]++;next}!a[$1]' file1 file2
工作原理:
FNR==NR
当您有两个(或更多)输入文件到awk时,NR
将在下一个文件的第一行重置为1,而FNR
将从它停止的位置继续递增。通过检查FNR==NR
,我们基本上检查我们当前是否正在解析第一个文件。
a[$1]++
如果我们 解析第一个文件(见上文),那么创建一个关联数组,第一个字段$1
作为键,并将值递增1.这实质上让我们创建一个'看到'列表。
next
此命令告诉awk不要处理任何进一步的命令并读入下一条记录并重新开始。我们这样做是因为file1仅用于设置关联数组
!a[$1]
此行仅在FNR==NR
为假时执行,即我们不解析file1,因此必须解析file2。然后,我们使用file2的第一个字段$1
作为索引到之前创建的“看到”列表的键。如果返回的值为0,则意味着我们没有在file1中看到它,因此我们应该打印这一行。相反,如果该值不为零,那么我们 在file1中看到它,因此我们不打印它的值。请注意,!a[$1]
相当于!a[$1]{print}
,因为未给出默认操作是打印整行。
答案 1 :(得分:1)
如果您不需要保留行的顺序,则可以在Bash,Korn shell或Z shell中使用进程替换以及join
和sort
实用程序:
join -v 2 <(sort file_1) <(sort file_2)
如果您使用的是没有进程替换的shell,则必须对文件进行预排序。