bash:加入和通信之间的区别


# 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未删除一些空格,结果会有所不同。

commjoin 之间有一些区别:

  1. comm比较整条线; join比较行内的字段。
  2. 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:]]*//'
}

最新更新