有没有什么工具可以获取文件A包含但文件B没有的行?我可以使用例如perl编写一些简单的脚本,但是如果已经存在类似的脚本,那么从现在开始我将节省时间。
有没有什么工具可以获取文件A包含但文件B没有的行?我可以使用例如perl编写一些简单的脚本,但是如果已经存在类似的脚本,那么从现在开始我将节省时间。
Answers:
是。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
-u
参数实际上确实接受一个数字参数,只要它后面没有空格即可。我以前使用它的方式的优点是它可以有或没有值都可以工作,因此您可以在该子命令例程中使用一些不返回值的东西。另一方面,大写字母“ -U”需要一个参数。
diff
管道工程款待表示感谢。
diff
是考虑了文件中的位置。
答案很大程度上取决于您要比较的文件的类型和格式。
如果您要比较的文件是已排序的文本文件,那么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
comm
; 不幸的是,comm
需要分类的文件
<()
?它有效,我明白了,但是这种怪异有名字吗?
comm
最初是由贝尔实验室的某人而不是rms于1973年撰写的。您指的是后来出现的GNU实现。多年来,Unix实用程序有许多不同的实现。
grep和comm(带有sort)方法在大文件上花费很长时间。SiegeX和ghostdog74共享了两种很棒的awk方法,用于在堆栈溢出中提取两个文件之一唯一的行:
$ awk 'FNR==NR{a[$0]++}FNR!=NR && !a[$0]{print}' file1 file2
$ awk 'FNR==NR{a[$0]++;next}(!($0 in a))' file1 file2
如果文件很大,而您的条目没有自定义顺序,则grep花费的时间太长。一个快速的替代方法是
sort file1 > 1
sort file2 > 2
diff 1 2 | grep "\>" | sed -e 's/> //'
[file2-file1结果显示到屏幕,管道传输到文件等。]
更改>
为<
将会得到相反的减法。rm 1 2