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

Sud*_*dar 88 unix text-files

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

现在我想找到a.txt不存在的行b.txt.

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

Sud*_*dar 151

你必须使用的命令是没有diff,但comm

comm -23 a.txt b.txt
Run Code Online (Sandbox Code Playgroud)

默认情况下,comm输出3列:left-only,right-only,both.的-1,-2-3开关抑制这些列.

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

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

  • 我将补充说,这只适用于两个文件都已排序的情况.(我知道OP提到他对文件进行了排序,但很多人,包括我在内,阅读了问题标题,然后跳到答案) (14认同)
  • @ user247866:幸运的是,comm很友好地告诉你他们是否没有排序:) (6认同)

Joh*_*ann 28

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

Alex
Bill
Fred
Run Code Online (Sandbox Code Playgroud)

而file2包含:

Alex
Bill
Bill
Bill
Fred
Run Code Online (Sandbox Code Playgroud)

然后comm -13 file1 file2会输出:

Bill
Bill
Run Code Online (Sandbox Code Playgroud)

就我而言,我只想知道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(使用fgrep)的5倍.


小智 8

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

diff a.txt b.txt  | grep \^\<
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用`diff --new-line-format = --unchanged-line-format = a.txt b.txt`来禁止打印新的和未更改的行. (3认同)

Bas*_*asj 5

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

comm -23 <(sort a.txt) <(sort b.txt)
Run Code Online (Sandbox Code Playgroud)

  • 这为我分配了大约15GB的内存,用于每个&lt;300 MB的文件... (2认同)