2
# comm -12 /tmp/src /tmp/txt | wc -l
  10338
# join /tmp/src /tmp/txt | wc -l
  10355

这两个文件都是单列字母数字字符串和sort-ed。他们不应该是一样的吗?


更新以下@Kevin-s 答案:

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.

4

4 回答 4

6

comm和之间有几个区别join

  1. comm比较整行;join比较行内的字段。
  2. comm打印整行;join可以打印选定的部分行。

当每个文件中只有一列数据时,差异相对较小。当您有多个列时,可能会有很多差异。

另请注意,在适当的情况下,join可以从一个文件输出数据的多个副本,同时与另一个文件的不同行连接。在我看来,这就像您的问题;您可能在其中一个文件中有一些重复的值。假设你有:

src           txt
123           123
              123
              123

如果你这样做comm -12 src txt,你将得到一行输出;如果你这样做join src txt,你会得到三行输出。这是意料之中的。

join命令还可以处理“外部联接”,其中第二个文件中缺少第一个文件中的一行的数据(SQL 方面的 LEFT OUTER JOIN)或反之亦然(RIGHT OUTER JOIN),或同时处理两者(a全外连接)。

总而言之,join是一个更复杂的命令,但它正在尝试做一个更复杂的工作。两者都有用;但它们在不同的地方很有用。

于 2011-08-29T19:23:27.377 回答
2

的主要用途join是选择共享一个字段的行,就像在数据库中一样。假设您有以下文件:

File A
Alice  24
Bill   16
Claire 31
John   10
John  -14

File B
Bill   Copenhagen
John   Adelaide

...您可以通过将文件 B 作为要加入的文件并将两者的第一个字段作为要加入的字段来从文件 A 中选择“John”和“Bill”行。但是,必须在该字段上对两个文件进行排序的要求在实践中相当麻烦。

于 2011-08-29T19:19:01.690 回答
1

我没有广泛使用过,但是从快速查看手册页和测试输入来看,似乎如果这两个文件不同,则 comm 会同时打印两者,而 join 只会打印匹配的行。 -12 解决了这个问题。您可以将两者的输出存储到文件中并进行比较以查看它们的不同之处。

$ echo -e '1\n2\n3\n5' > a
$ echo -e '1\n2\n4\n5' > b
$ comm a b
                1
                2
3
        4
                5
$ join a b
1
2
5
$

编辑: Join 仅比较第一个空格分隔的字段,但 comm 比较整行。因此,行上的任何空格都会使输出不同。

于 2011-08-29T18:23:56.547 回答
1

使用[[:space:]](而不是[:space:])用 . 去除空格sed

# compare
{
echo '   abc' | sed 's/^[:space:]*//'
echo '   abc' | sed 's/^[[:space:]]*//'
}
于 2011-08-30T11:23:53.947 回答