2015-03-02 75 views
0

我有兩個TSV文件,我想根據第一列中的通用性合併它們。該列沒有標題,但數據是每個公司的名稱。將基於列的TSV合併到多行

我有一個接近我想要的awk代碼。問題是,我想合併公司每一次提到的信息,而不僅僅是第一次。

items.tsv看起來是這樣的:

IBM 0.0107 100.0% 
APPL 0.0457 98.0% 
GOOGL 0.0227 100.0% 
GOOGL 0.0197 100.0% 
GOOGL 0.0997 90.0% 
GOOGL 0.0397 10.0% 

vendors.tsv:

IBM Dec 2011 
APPL Jan 2014 
GOOGL June 2015 

隨着我的代碼,輸出爲:

IBM 0.0107 100.0% Dec 2011 
APPL 0.0457 98.0% Jan 2014 
GOOGL 0.0227 100.0% June 2015 

三線缺失!所需的輸出是這樣的:

IBM 0.0107 100.0% Dec 2011 
APPL 0.0457 98.0% Jan 2014 
GOOGL 0.0227 100.0% June 2015 
GOOGL 0.0197 100.0% June 2015 
GOOGL 0.0997 90.0% June 2015 
GOOGL 0.0397 10.0% June 2015 

這是我一直在使用的代碼:

awk ' 
    BEGIN {FS=OFS="\t"} 
    NR==FNR {a[$1] = $2 FS $3; next} 
    $1 in a {print $1, a[$1], $2, $3} 
' items.tsv vendors.tsv 

行的順序並不重要。數據由標籤\ t分隔。我希望有人能幫助!

(請注意,awk的代碼是相同的東西我一直在使用,輸出由我打完了,所以\ t是一些地方定期空間等)

回答

1

的問題是隻是順序輸入文件。通過NR == FNR成語,(通常)將第一個文件讀入數組,然後爲第二個文件中的每個記錄輸出一行,使用該數組與第一個文件中的信息「加入」。由於您將供應商文件作爲第二個文件,因此讀入了三條記錄並寫出了三條記錄。

同樣重要的是,第一個文件具有唯一的鍵作爲數組索引。只能有一個a["GOOGL"],但通過切換輸入文件的順序,該問題也會消失。

$ cat vendors.tsv 
IBM Dec 2011 
APPL Jan 2014 
GOOGL June 2015 

$ cat item.tsv 
IBM 0.0107 100.0% 
APPL 0.0457 98.0% 
GOOGL 0.0227 100.0% 
GOOGL 0.0197 100.0% 
GOOGL 0.0997 90.0% 
GOOGL 0.0397 10.0% 

$ cat merge.awk 
BEGIN {FS=OFS="\t"} 
NR==FNR {a[$1] = $2 FS $3; next} 
$1 in a { print $1, $2, $3, a[$1] } 

$ awk -f merge.awk vendors.tsv item.tsv 
IBM 0.0107 100.0% Dec 2011 
APPL 0.0457 98.0% Jan 2014 
GOOGL 0.0227 100.0% June 2015 
GOOGL 0.0197 100.0% June 2015 
GOOGL 0.0997 90.0% June 2015 
GOOGL 0.0397 10.0% June 2015