2012-11-14 25 views
16

我需要在兩個域上連接兩個文件。不過,我應該檢索文件1中的所有值,即使連接失敗它像一個左外連接。unix中兩個文件的左外連接

文件1:

01|a|jack|d 
02|b|ron|c 
03|d|tom|e 

文件2:

01|a|nemesis|f 
02|b|brave|d 
04|d|gorr|h 

輸出:使用

01|a|jack|d|nemesis|f 
02|b|ron|c|brave|d 
03|d|tom|e|| 

回答

19

這是join -t '|' file1 file2 -a1

選項:

t:分隔符。
a:決定必須打印不成對的行的文件編號。

join -t '|' file1 file2 -a2會做右外連接

樣品試驗

[[email protected] test]$ cat f1 
    01|a|jack|d 

    02|b|ron|c 

    03|d|tom|e 
    [[email protected] test]$ cat f2 
    01|a|nemesis|f 

    02|b|brave|d 

    04|d|gorr|h 
    [[email protected] test]$ join -t '|' f1 f2 -a1 
    01|a|jack|d|a|nemesis|f 

    02|b|ron|c|b|brave|d 

    03|d|tom|e 
+1

你說的沒錯,你的輸出他的輸出相匹配。案件關閉。祝你們好運。 – shellter

+0

@shellter。不完全的。在記錄末尾有一個缺失的管道,沒有在idm的帖子中解決的匹配。儘管如此,爲了成爲讓大多數人找到Linux外部連接函數的策略的一種策略,我還是給出了一個策略。 –

4

做的正是這個問題問的有點比以前的答案比較複雜,需要這樣的事:

sed 's/|/:/2' file1 | sort -t: >file1.tmp 
sed 's/|/:/2' file2 | sort -t: >file2.tmp 
join -t':' file1.tmp file2.tmp -a1 -e'|' -o'0,1.2,2.2' | tr ':' '|' 

Unix的加入只能加入上單個字段AFAIK,因此您必須使用使用不同分隔符的文件「在兩個字段上加入兩個文件」,在本例中爲前兩個字段。我將使用冒號,但是如果在任何輸入中都存在,則需要使用其他內容,例如製表符可能是生產使用的更好選擇。我還重新對新化合物字段sort -t:中的輸出進行排序,對於示例輸入文件而言這些輸出沒有什麼區別,但是對於真實世界的數據則沒有區別。 sed 's/|/:/2'用文件中每行的冒號替換第二次出現的管道。

file1.tmp

01|a:jack|d 
02|b:ron|c 
03|d:tom|e 

file2.tmp

01|a:nemesis|f 
02|b:brave|d 
04|d:gorr|h 

現在我們使用join輸出由tr過濾有一些更高級的選項:

  • -t':'指定臨時冒號分隔符
  • -a1左外連接
  • -e'|'指定失敗連接的替換字符串,基本上是最終輸出分隔符N-1次,其中N是連接到file2.tmp中冒號右側的管道分隔字段的數目。在這種情況下,N = 2表示一個管道字符。
  • -o'0,1.2,2.2'指定輸出格式:
    • 0聯接字段
    • 1.2字段2 file1.tmp,即一切結腸
    • 的右
    • 2.2字段file2.tmp
  • tr ':' '|' 2最後,我們將冒號轉換回管道作爲最終輸出。

輸出匹配現在的問題樣本輸出到底哪個以前的答案沒有做:

01|a|jack|d|nemesis|f 
02|b|ron|c|brave|d 
03|d|tom|e|| 
+0

精心設計的迴應,以及每一個細節的絕佳解釋。 –