查找文件中没有出现在另一个文件中的行

我有两个文件(比方说 a.txtb.txt) ,它们都有一个名称列表。我已经对这两个文件运行了 sort

现在我想从 a.txt中找出在 b.txt中不存在的行。

(我花了很多时间来寻找这个问题的答案,所以记录下来以备将来参考)

90595 次浏览

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

comm -23 a.txt b.txt

默认情况下,comm输出3列: 只能左转只有正确都有-1-2-3开关抑制这些列。

因此,-23隐藏了 只有正确都有列,显示仅出现在第一个(左)文件中的行。

如果希望查找同时出现在这两个列中的行,可以使用 -12,它隐藏了 只能左转只有正确列,只留下 都有列。

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

Alex
Bill
Fred

文件2包含:

Alex
Bill
Bill
Bill
Fred

然后 comm -13 file1 file2将输出:

Bill
Bill

在我的例子中,我只想知道 file2中的每个字符串都存在于 file1中,而不管该行在每个文件中出现了多少次。

解决方案1: sort使用 -u(惟一)标志:

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

解决方案2: (我找到的第一个“有效”的答案)来自 Unix.stackexchange:

fgrep -v -f file1 file2

注意,如果 file2包含 file1中根本不存在的重复行,fgrep将输出每个重复行。还要注意,我在单台笔记本电脑上对单个(相当大)数据集进行的完全非科学的测试显示,解决方案1(使用 comm)几乎比解决方案2(使用 fgrep)快5倍。

我不知道为什么说 diff不应该被使用。我将使用它来比较两个文件,然后只输出左边文件中的行,而不是右边文件中的行。这样的行用差异与 <标记,所以它足以在行的开头抓取该符号

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

如果文件还没有被排序,你可以使用:

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