2011-08-29 81 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:]]*//' 
}