如何基于两个文件之间的公共字段使用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 

Solutions Collecting From Web of "如何基于两个文件之间的公共字段使用AWK删除一个文件中的重复行?"

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为false时执行,即我们解析file1,因此必须解析file2。 然后,我们使用file2的第一个字段$1作为索引到我们之前创建的“可见”列表中。 如果返回的值是0,这意味着我们没有在file1中看到它,因此我们应该打印这一行。 相反,如果这个值不是零,那么我们在file1中看到它,所以我们不应该打印它的值。 请注意!a[$1]相当于!a[$1]{print}因为没有给出的默认动作是打印整行。

如果您不需要保留行的顺序,则可以在Bash,Korn shell或Z shell中使用进程替换以及joinsort实用程序:

 join -v 2 <(sort file_1) <(sort file_2) 

如果你使用没有进程替换的shell,你将不得不预先对文件进行排序。