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

时间:2013-01-23 05:32:40

标签: unix text-files

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

现在我想查找来自a.txt的{​​{1}}中没有的行。

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

4 个答案:

答案 0 :(得分:135)

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

comm -23 a.txt b.txt

默认情况下,comm输出3列:仅限左侧仅右侧两者-1-2-3开关会禁止这些列。

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

如果要查找同时显示的行,可以使用-12,其中隐藏仅左仅限右侧列,只有两个列。

答案 1 :(得分:25)

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

Alex
Bill
Fred

file2包含:

Alex
Bill
Bill
Bill
Fred

然后comm -13 file1 file2会输出:

Bill
Bill

在我的情况下,我只想知道file2中的每个字符串都存在于file1中,无论每行中出现多少次该行。

解决方案1:使用-u的{​​{1}}(唯一)标记:

sort

解决方案2:(我发现的第一个"工作"答案)来自unix.stackexchange

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

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

答案 2 :(得分:5)

我不确定为什么不应该使用diff。我会用它来比较两个文件,然后只输出左边文件中的行而不是右边的行。这些行由diff <标记,因此在行的开头grep该符号就足够了

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

答案 3 :(得分:4)

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

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