我有时需要比较两个文本文件。显然,diff
显示了不同之处,也隐藏了相似之处,这就是关键所在。
假设我想对这些文件进行其他比较:集合并、交集和减法,将每一行作为集合中的一个元素。
是否有类似的简单通用实用程序或一行程序可以做到这一点?
例子:
a.txt
john
mary
b.txt
adam
john
$> set_union a.txt b.txt
john
mary
adam
$> set_intersection a.txt b.txt
john
$> set_difference a.txt b.txt
mary
联盟:sort -u
文件…
交集:sort
文件… | uniq -d
整体差异(仅在一个文件中的元素):sort
文件… | uniq -u
数学差异(元素在一个文件中只出现一次):sort
文件… | uinq -u | sort - <(sort -u
fileX ) | uniq -d
前两个命令获取所有唯一元素。然后我们将它与我们感兴趣的文件合并。sort - <(sort -u
fileX )
:
-
将处理stdin(即所有唯一元素的列表)。
<(...)
执行命令,将输出写入临时文件,并将文件的路径传递给命令。
如果您想获得两个文件之间的公共行,您可以使用comm实用程序。
A.txt:
A
B
C
B.txt
A
B
D
,然后,使用comm将得到:
$ comm <(sort A.txt) <(sort B.txt)
A
B
C
D
在第一列中,您拥有第一个文件中而不是第二个文件中的内容。
在第二列中,您拥有第二个文件中而不是第一个文件中的内容。
第三列是两个文件中的内容
如果您不介意使用一点Perl,并且如果您的文件大小合理,可以将它们写入散列,那么您可以将这些文件收集为两个散列来执行:
#...get common keys in an array...
my @both_things
for (keys %from_1) {
push @both_things, $_ if exists $from_2{$_};
}
#...put unique things in an array...
my @once_only
for (keys %from_1) {
push @once_only, $_ unless exists $from_2($_);
}
我不能评论Aaron Digulla的答案,尽管它被接受,但实际上并没有计算集合差。
给定输入的集差AB应该只返回mary
,但接受的答案也错误地返回adam
。
这个答案有一个awk的一行代码,可以正确地计算集合差值:
awk 'FNR==NR {a[$0]++; next} !a[$0]' b.txt a.txt