2012-05-23 29 views
9

我正在使用標準連接命令來加入兩個基於column1的已排序文件。 該命令是簡單的連接file1 file2> output_file。加入多個文件

但是,如何使用相同的技術加入3個或更多文件? join file1 file2 file3> output_file 上面的命令給了我一個空文件。 我認爲sed可以幫助我,但我不太清楚如何?

回答

19

man join

NAME 
     join - join lines of two files on a common field 

SYNOPSIS 
     join [OPTION]... FILE1 FILE2 

它只有文件的工作。

如果你需要加入三個,也許你可以先加入前兩個,然後加入第三個。

嘗試:

join file1 file2 | join - file3 > output 

應該加入這三個文件,而不需要創建中間臨時文件。 -告訴加入命令來讀取從stdin

+0

第二次連接的連字符是什麼意思?它是加入的特殊符號? –

+0

看到我的更新。 '-'被許多unix程序理解爲標準輸入/標準輸出的簡寫 – mata

+0

你明白了。謝謝。 –

0

在一個共同的字段上加入連線兩個文件。如果你想加入更多 - 成對地完成。首先加入前兩個文件,然後用第三個文件加入結果等。

2

man頁的join指出它只適用於兩個文件。所以,你需要創建和中間文件,刪除之後,即:

> join file1 file2 > temp 
> join temp file3 > output 
> rm output 
+4

或'加入<(加入文件1文件2)file3' – Kevin

+0

@Kevin甜!不知道那個! – Gnosophilon

9

一個第一輸入流可以通過遞歸地構建的join個管道加入多個文件(N> = 2):

#!/bin/sh 

# multijoin - join multiple files 

join_rec() { 
    if [ $# -eq 1 ]; then 
     join - "$1" 
    else 
     f=$1; shift 
     join - "$f" | join_rec "[email protected]" 
    fi 
} 

if [ $# -le 2 ]; then 
    join "[email protected]" 
else 
    f1=$1; f2=$2; shift 2 
    join "$f1" "$f2" | join_rec "[email protected]" 
fi 
+0

絕對是我最喜歡的答案!但是,我用'f1 = $ 1替換了'join_rec'函數的主體。 F2 = $ 2;班次2; if [$#-gt 0];然後; 加入「$ f1」「$ f2」| join_rec - 「$ @」; 其他; 加入「$ f1」「$ f2」;爲了消除對第二個if的需要,該調用看起來像'join_rec「$ @」' – user43791

+0

@ack是否可以在輸出中添加文件名作爲標題? – user1883491

7

我知道這是一箇舊的問題,但供將來參考。 如果你知道你想加入的文件有一個像這裏問題一樣的模式,例如file1 file2 file3 ... fileN 然後,你可以簡單地用這個命令

cat file* > output 

如果輸出將是一系列被加入了按字母順序排列的加入文件加入他們的行列。

+0

這對文本文件非常適用。如何使用其他命令/軟件包/軟件分割的二進制文件。 –

+2

那麼你有可能在每個文件中有一些標題,表明它是什麼類型的文件,所以這是不夠的,但你應該搜索其他這樣的問題,我相信有人已經解決了它 – rsz

+2

問題是將輸入文件中的相應行連接在一起。不連接它們。 –

3

我爲此創建了一個函數。第一個參數是輸出文件,其餘參數是要連接的文件。

function multijoin() { 
    out=$1 
    shift 1 
    cat $1 | awk '{print $1}' > $out 
    for f in $*; do join $out $f > tmp; mv tmp $out; done 
} 

用法:

multijoin output_file file* 
+0

謝謝,這很有用。如果有人想添加標題,那麼sed -i'1i header_text'output_file –