从文件中查找不在另一个文件中的行

我有两个文件(比如说a.txtb.txt ),这两个文件都有一个名称列表。 我已经在这两个文件上运行sort

现在我想从a.txt中findb.txt中不存在的b.txt

(我花了很多时间find这个问题的答案,所以logging下来供将来参考)

你必须使用的命令不是diff而是comm

 comm -23 a.txt b.txt 

默认情况下, comm输出3列: 只有左,只有 -1-2-3开关禁止这些列。

因此, -23隐藏了右侧两侧的列,显示仅出现在第一个(左侧)文件中的行。

如果要查找出现在两者中的行,可以使用-12 ,这隐藏了只有左侧列和 右侧列,只留下列。

简单的答案不适用于我,因为我没有意识到comm匹配行,所以一个文件中的重复行将被打印为不存在于另一个。 例如,如果file1包含:

 Alex Bill Fred 

而file2包含:

 Alex Bill Bill Bill Fred 

然后comm -13 file1 file2会输出:

 Bill Bill 

在我的情况下,我只想知道file2中的每个string都存在于file1中,而不pipe每个文件中该行发生了多less次。

解决scheme1:使用-u (唯一)标志对以下内容进行sort

comm -13 <(sort -u file1) <(sort -u file2)

解决scheme2 🙁我find的第一个“工作”的答案)从unix.stackexchange :

fgrep -v -f file1 file2

请注意,如果file2包含file1中根本不存在的重复行,则fgrep将输出每个重复行。 另外请注意,对于单个(相当大)的数据集,在单台笔记本电脑上进行的完全非科学testing显示,解决scheme1(使用comm )比解决scheme2(使用fgrep )快近5倍。

如果文件不能被sorting,你可以使用:

 comm -23 <(sort a.txt) <(sort b.txt) 

我不知道为什么有人说diff不应该用。 我会用它来比较这两个文件,然后只输出左边的文件,但不是右边的文件。 这样的行由diff标记,所以只需在行的开始处对该符号进行grep即可

 diff a.txt b.txt | grep \^\<