# comm -12 /tmp/src /tmp/txt | wc -l
10338
# join /tmp/src /tmp/txt | wc -l
10355
这两个文件都是字母数字字符串和 sort
-ed 的单列。 它们不应该是一样的吗?
更新了以下@Kevin答案:
cat /tmp/txt | sed 's/^[:space:]*//' > /tmp/stxt
cat /tmp/src | sed 's/^[:space:]*//' > /tmp/ssrc
结果是:
#join /tmp/ssrc /tmp/stxt | wc -l
516
# comm -12 /tmp/ssrc /tmp/stxt | wc -l
513
关于手动检查diff
-s ...由于sed
未删除一些空格,结果会有所不同。
comm
和 join
之间有一些区别:
-
comm
比较整条线;join
比较行内的字段。 -
comm
打印整行;join
可以打印行的选定部分。
当每个文件中都有一列数据时,差异相对较小。 当您有多个列时,可能会有很多差异。
另请注意,在适当的情况下,join
可以从一个文件输出数据的多个副本,同时使用另一个文件的不同行连接。 在我看来,这就像你的问题;其中一个文件中可能有一些重复的值。 假设您有:
src txt
123 123
123
123
如果你做comm -12 src txt
,你会得到一行输出;如果你做join src txt
,你会得到三行输出。 这是意料之中的。
join
命令还可以处理"外连接",即第一个文件中一行的第二个文件中缺少数据(就 SQL 而言是左外连接(,反之亦然(右外连接(,或同时处理两者(完全外连接(。
总而言之,join
是一个更复杂的命令,但它试图做一个更复杂的工作。 两者都很有用;但它们在不同的地方很有用。
join
的主要用途是选择共享一个字段的行,就像在数据库中一样。 假设您有以下文件:
File A
Alice 24
Bill 16
Claire 31
John 10
John -14
File B
Bill Copenhagen
John Adelaide
。您可以从文件 A 中选择"John"和"Bill"行,方法是将文件 B 作为要连接的文件,并将两者的第一个字段作为要连接的字段。 但是,必须对该字段对两个文件进行排序的要求在实践中相当麻烦。
我还没有广泛使用,但是从手册页和测试输入的快速浏览来看,似乎如果两个文件不同,comm 会同时打印两者,并且 join 只打印匹配的行。 -12 处理了这一点。 您可以将两者的输出存储到文件中,并进行差异以查看它们有何不同。
$ echo -e '1n2n3n5' > a
$ echo -e '1n2n4n5' > b
$ comm a b
1
2
3
4
5
$ join a b
1
2
5
$
编辑:Join 仅比较第一个空格分隔的字段,但 comm 比较整行。 因此,行上的任何空格都会使输出不同。
使用 [[:space:]]
(而不是 [:space:]
(去除带有 sed
的空格。
# compare
{
echo ' abc' | sed 's/^[:space:]*//'
echo ' abc' | sed 's/^[[:space:]]*//'
}