如何使用AWK基于两个文件之间的公共字段删除一个文件上的重复行?

Ton*_*ony 2 unix awk

我有两个文件

  1. 文件1包含3个字段

  2. 文件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 
Run Code Online (Sandbox Code Playgroud)

Sie*_*geX 6

awk 'FNR==NR{a[$1]++;next}!a[$1]' file1 file2

这个怎么运作:

FNR==NR
Run Code Online (Sandbox Code Playgroud)

当您有两个(或更多)输入文件到awk时,NR将在下一个文件的第一行重置为1,而FNR将从它停止的位置继续递增.通过检查FNR==NR我们基本上检查我们当前是否正在解析第一个文件.

a[$1]++
Run Code Online (Sandbox Code Playgroud)

如果我们正在解析第一个文件(见上文),那么创建一个关联数组,第一个字段$1作为键,并将值递增1.这基本上允许我们创建一个"看到"列表.

next
Run Code Online (Sandbox Code Playgroud)

此命令告诉awk不要处理任何进一步的命令并读入下一条记录并重新开始.我们这样做是因为file1仅用于设置关联数组

!a[$1]
Run Code Online (Sandbox Code Playgroud)

此行仅在FNR==NRfalse 时执行,即我们解析file1,因此必须解析file2.然后,我们使用$1file2 的第一个字段作为索引到我们之前创建的"see"列表的键.如果返回的值为0,则意味着我们没有在file1中看到它,因此我们应该打印这一行.相反,如果该值不为零,那么我们看到它在文件1,因此,我们应该不会打印出它的价值.请注意,这!a[$1]相当于!a[$1]{print}因为未给出一个时的默认操作是打印整行.