bash:join和comm之间的区别

时间:2011-08-29 18:12:32

标签: bash join comm

# 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 个答案:

答案 0 :(得分:4)

commjoin之间存在一些差异:

  1. comm比较整行; join比较行内的字段。
  2. comm打印整行; join可以打印选定的部分内容。
  3. 如果每个文件中只有一列数据,则差异相对较小。当你有多个列时,可能会有很多不同。

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

    src           txt
    123           123
                  123
                  123
    

    如果你comm -12 src txt,你将得到一行输出;如果你做join src txt,你会得到三行输出。这是预期的。

    join命令还可以处理'外连接',其中第一个文件中的第二个文件中缺少数据(根据SQL,LEFT OUTER JOIN),反之亦然(右外连接) ),或同时两者(完全外部加入)。

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

答案 1 :(得分:2)

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

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

File B
Bill   Copenhagen
John   Adelaide

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

答案 2 :(得分:1)

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

# compare
{
echo '   abc' | sed 's/^[:space:]*//'
echo '   abc' | sed 's/^[[:space:]]*//'
}

答案 3 :(得分:0)

我没有广泛使用过,但是从快速查看手册页和测试输入看来,如果两个文件不同,则会打印两个并且仅连接打印匹配的行。 -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比较整行。因此,线上的任何空格都会使输出不同。