128

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

现在我想查找a.txt其中不存在的行b.txt

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

4

4 回答 4

211

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

comm -23 a.txt b.txt

默认情况下,comm输出 3 列:left-onlyright-onlyboth-1和开关抑制这些列-2-3

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

如果您想查找出现在两者中的行,您可以使用-12,它隐藏仅左列和仅,只留下列。

于 2013-01-23T05:32:39.723 回答
40

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

Alex
Bill
Fred

file2 包含:

Alex
Bill
Bill
Bill
Fred

然后comm -13 file1 file2会输出:

Bill
Bill

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

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

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

解决方案2:(我找到的第一个“工作”答案)来自unix.stackexchange

fgrep -v -f file1 file2

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

于 2014-09-30T20:50:42.923 回答
17

我不知道为什么有人说不diff应该使用它。我会用它来比较两个文件,然后只输出左侧文件中的行,而不是右侧文件中的行。此类行由 diff with 标记,<因此只需在行首 grep 该符号即可

diff a.txt b.txt  | grep \^\<
于 2016-06-19T09:30:32.937 回答
11

如果文件尚未排序,您可以使用:

comm -23 <(sort a.txt) <(sort b.txt)
于 2017-07-21T11:30:56.697 回答