2011-08-29 80 views
1
# comm -12 /tmp/src /tmp/txt | wc -l 
    10338 
# join /tmp/src /tmp/txt | wc -l 
    10355 

这两个文件都是单列字母数字字符串和sort -ed。他们不应该一样吗?bash:连接和通信之间的区别


更新以下@凯文的回答如下:

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取出。

+0

这真的不是一个bash问题。 –

+0

@keith Thompson它可能是命令特定的 - 但我在为bash脚本选择它们时遇到了它们。因此标签。 – Tathagata

回答

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 
$ 

编辑: 加入只比较第一空格分隔领域,但COMM整条生产线进行比较。线上的任何空格都会使输出不同。

+0

我正在使用'comm -12'来抑制FILE1,FILE2唯一的行。 'diff'-s太大 - 伤了眼睛;) – Tathagata

+1

我现在看到我错过了。在进一步检查手册页之后,似乎在第一个以空格分隔的字段上加入连接,但comm在整行上加入。输入文件中是否有空格? – Kevin

+0

好点...我会尝试'sed'的空间,看看是否有区别...:D – Tathagata

2

join的主要功能是选择共享一个字段的行,就像你可以在数据库中做的那样。假设你有以下文件:

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

File B 
Bill Copenhagen 
John Adelaide 

...你可以选择“约翰”和“条例”从文件中通过给文件B作为文件加入用线条,都为第一场该领域加入。虽然这两个文件必须被排序在该领域的要求在实践中是相当繁琐的。

4

commjoin之间的一些差异:

  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)中缺少数据的'外连接',或者(一个完整的外部联接)。

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

+0

谢谢你的答案,真的很丰富。我通常在列上排序-k,但从未习惯使用join,并且发现自己编写了长长的'awk'关联数组来比较文件。lulz:D – Tathagata

1

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

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