有没有什么工具可以获取文件A包含但文件B不包含的行?我可以用 perl 等制作一个简单的脚本,但如果类似的东西已经存在,我将从现在开始节省时间。
答案1
是的。用于在文件中搜索文本字符串的标准grep
工具可用于从一个文件中减去另一个文件中的所有行。
grep -F -x -v -f fileB fileA
这是通过使用 fileB 中的每一行作为模式 ( -f fileB
) 并将其视为要匹配的纯字符串(不是常规正则表达式) ( -F
) 来实现的。您强制匹配在整行 ( -x
) 上进行,并仅打印不匹配的行 ( -v
)。因此,您打印的 fileA 中的行不包含与 fileB 中的任何行相同的数据。
此解决方案的缺点是它没有考虑行顺序,如果您的输入在不同位置有重复行,您可能无法得到您所期望的结果。解决方案是使用真正的比较工具,例如diff
.您可以通过创建一个 diff 文件来执行此操作,其中上下文值位于文件中 100% 的行,然后解析它以仅查找将文件 A 转换为文件 B 时将删除的行。(请注意,此命令还会删除 diff获得正确的行后进行格式化。)
diff -U $(wc -l < fileA) fileA fileB | sed -n 's/^-//p' > fileC
答案2
答案很大程度上取决于您正在比较的文件的类型和格式。
如果您要比较的文件是排序的文本文件,则 Richard Stallman 和 Davide McKenzie 编写的 GNU 工具称为comm
可以执行您想要的过滤。它是 coreutils 的一部分。
例子
假设您有以下 2 个文件:
$ cat a
1
2
3
4
5
$ cat b
1
2
3
4
5
6
b
文件中不存在于文件中的行a
:
$ comm <(sort a) <(sort b) -3
6
答案3
答案4
如果文件很大并且您的条目没有自定义顺序,则 grep 会花费太长的时间。一个快速的替代方案是
sort file1 > 1
sort file2 > 2
diff 1 2 | grep "\>" | sed -e 's/> //'
[file2-file1 结果显示到屏幕、通过管道传送到文件等]
更改>
为<
将得到相反的减法。rm 1 2