是否有一种工具可以获取一个文件中不在另一个文件中的行?

dai*_*isy 128 command-line

是否有任何工具可以获取文件 A 包含但文件 B 不包含的行?我可以使用例如 perl 编写一个简单的脚本,但是如果已经存在类似的东西,我会从现在开始节省我的时间。

Cal*_*leb 185

是的。grep用于在文件中搜索文本字符串的标准工具可用于从另一个文件中减去一个文件中的所有行。

grep -F -x -v -f fileB fileA
Run Code Online (Sandbox Code Playgroud)

这是通过将 fileB 中的每一行用作模式 ( -f fileB) 并将其视为要匹配的纯字符串(而不是常规正则表达式) ( -F) 来实现的。您强制匹配发生在整行 ( -x) 并仅打印出不匹配的行 ( -v)。因此,您要打印出 fileA 中不包含与 fileB 中任何行相同数据的行。

此解决方案的缺点是它没有考虑行顺序,如果您的输入在不同的地方有重复的行,您可能无法获得预期的结果。解决方案是使用真正的比较工具,例如diff. 您可以通过在文件中 100% 的行处创建一个具有上下文值的 diff 文件,然后将其解析为仅在将文件 A 转换为文件 B 时将被删除的行来实现。(注意此命令还会删除 diff在获得正确的行后进行格式化。)

diff -U $(wc -l < fileA) fileA fileB | sed -n 's/^-//p' > fileC
Run Code Online (Sandbox Code Playgroud)


小智 64

答案很大程度上取决于您要比较的文件的类型和格式。

如果您正在比较的文件是排序的文本文件,那么由 Richard Stallman 和 Davide McKenzie 编写的 GNU 工具comm可能会执行您想要的过滤。它是 coreutils 的一部分。

例子

假设您有以下 2 个文件:

$ cat a
1
2
3
4
5

$ cat b
1
2
3
4
5
6
Run Code Online (Sandbox Code Playgroud)

文件b中不在文件中的行a

$ comm <(sort a) <(sort b) -3
    6
Run Code Online (Sandbox Code Playgroud)

  • 所以对它们进行排序?comm &lt;(排序 a) &lt;(排序 b) -1 -2 (11认同)
  • `comm` 最初是大约 1973 年由贝尔实验室的某个人编写的,而不是 rms。您指的是后来出现的 GNU 实现。多年来,Unix 实用程序有许多不同的实现。 (4认同)
  • @mlissner `&lt;()` 也称为 [进程替换](http://tldp.org/LDP/abs/html/process-sub.html)。 (2认同)

JJS*_*JJS 37

堆栈溢出...

comm -23 文件 1 文件 2

-23 抑制文件 2 (-2) 中的行和同时出现在两者 (-3) 中的行,只留下文件 1 中的唯一行。必须对文件进行排序(它们在您的示例中),但如果没有,请先通过 sort 管道它们。

请参阅此处的手册页

-1 suppress column 1 (lines unique to FILE1)
-2 suppress column 2 (lines unique to FILE2)
-3 suppress column 3 (lines that appear in both files)
Run Code Online (Sandbox Code Playgroud)


小智 9

grep 和 comm(带排序)方法在大文件上需要很长时间。SiegeX 和 ghostdog74 共享了两种很棒的awk 方法,用于在 Stack Overflow 上提取两个文件之一独有的行

$ awk 'FNR==NR{a[$0]++}FNR!=NR && !a[$0]{print}' file1 file2

$ awk 'FNR==NR{a[$0]++;next}(!($0 in a))' file1 file2
Run Code Online (Sandbox Code Playgroud)

  • 如果您对大文件执行此操作,那么将大文件加载到关联数组的内存限制将令人望而却步。 (3认同)

小智 5

如果文件很大并且您没有自定义条目的顺序,则 grep 花费的时间太长。一个快速的选择是

sort file1 > 1 
sort file2 > 2 
diff 1 2 | grep "\>" | sed -e 's/> //'
Run Code Online (Sandbox Code Playgroud)

[file2-file1 结果到屏幕,管道到文件等]

更改><将得到相反的减法。rm 1 2