2015-11-13 41 views
1

連接多個TSV文件中選擇列我有類似以下在bash

"gene_id" "Pattern1" "Pattern2" "Pattern3" "Pattern4" "Pattern5" "MAP" "PPDE" 
"ENSG00000119771.13" 3.11528786599051e-18 2.52650109640992e-13 6.25109524320237e-09 0.345846257420197 0.654153736328455 "Pattern5" 1 
"ENSG0000.4" 1.75016991626305e-36 3.98804090894939e-19 0.63423772228367 3.8159144080782e-21 0.36576227771633 "Pattern3" 1 
"ENSG00000128567.15" 1.10722918612618e-23 7.62691311068806e-07 5.77031364194955e-06 5.13675840911147e-21 0.999993466995047 "Pattern5" 1 
"ENSG00000130182.6" 9.75717082221716e-22 1.27675651077242e-12 0.469972541094369 1.13677117238758e-12 0.530027458903217 "Pattern5" 1 
"ENSG00000131914.9" 3.1627489688037e-41 1.00274706758683e-22 0.0578584524816503 6.98718794692175e-22 0.94214154751835 "Pattern5" 1 

現在我想將它們加入到一個文件中,使我得到了一堆的製表符分隔文本文件

"gene_id" "Pattern5" "Pattern5" "Pattern5" "Pattern5" "Pattern5" 

其中每個Pattern5列來自一個文件。

我嘗試了一些東西與

cut -f 6 <file> 

paste <file1> <file2> ... 

,但我無法正確地結合起來。

感謝您的幫助!

UPDATE: 我儘量給你一個可測試的例子作爲輸入這裏:

<file1> 
gene_id Pattern1 Pattern2 Pattern3 Pattern4 Pattern5 
ENSG00000119771 1 2 3 4 5 
ENSG0000
ENSG00000128567 1 2 3 4 5 
ENSG00000130182 1 2 3 4 5 
ENSG00000131914 1 2 3 4 5 

<file2>   
gene_id Pattern1 Pattern2 Pattern3 Pattern4 Pattern5 
ENSG00000119771 6 7 8 9 10 
ENSG0000
ENSG00000128567 6 7 8 9 10 
ENSG00000130182 6 7 8 9 10 
ENSG00000131914 6 7 8 9 10 

<file3>    
gene_id Pattern1 Pattern2 Pattern3 Pattern4 Pattern5 
ENSG00000119771 11 12 13 14 15 
ENSG0000
ENSG00000128567 11 12 13 14 15 
ENSG00000130182 11 12 13 14 15 
ENSG00000131914 11 12 13 14 15 

和所需的輸出將

gene_id Pattern5_file1 Pattern5_file2 Pattern5_file3 
ENSG00000119771 5 10 15 
ENSG0000
ENSG00000128567 5 10 15 
ENSG00000130182 5 10 15 
ENSG00000131914 5 10 15 

UPDATE2: 我想盡了辦法Ed Morton:

awk ' 
BEGIN { FS=OFS="\t" } FNR==1{ARGIND++} 
{ genes[$1]; val[$1,ARGIND] = $5 } 
END { 
    for (gene in genes) { 
     printf "%s%s", gene, OFS 
     for (file=1; file<=ARGIND; file++) { 
      printf "%s%s", val[gene,file], (file<ARGIND?OFS:ORS) 
     } 
    } 
} ' $files 

但輸出是不正確的格式:

ENSG00000128567 4 9 14 
ENSG00000130182 4 9 14 
ENSG00000119771 4 9 14 
gene_id Pattern4 Pattern4 Pattern4 
ENSG00000131914 4 9 14 
ENSG0000
+0

列索引也將是不錯的文件名作爲連接文件中的列標題例如 ''''gene_id「」「」「」「」「'''' – Max

+0

P.P.S.我有很多文件(〜200),所以我要求一個通用的解決方案,我只是在命令中插入一個文件列表 – Max

+0

注意到你試過剪切和粘貼,我沒有看到任何排序或關聯的嘗試。那麼第1列的gene_id是否與所有文件完全相同?所以我們不必擔心匹配行。那麼文件1,第1列的第7行與第200行文件中第1列第7行的值相同? – user454038

回答

2

嘗試這一個

#!/bin/bash 

paste file1 file2 file3 | awk -v patternIdx=6 ' 

function printPattern(idx, isFirstLine) { 
    for (i = 1; i <= NF; ++i) { 
     if (i == 1) 
      printf "%s ", $i; 
     else if (isFirstLine && i % patternIdx == 0) 
      printf "%s_file%d ", $i, i/patternIdx; 
     else if (i % patternIdx == 0) 
      printf "%d ", $i; 
    } 
    printf "\n" 
} 
{ 
    if (NR == 1) 
     printPattern(patternIdx, 1); 
    else 
     printPattern(patternIdx, 0); 
}' 

patternIdx是Pattern5

+0

謝謝,那看起來很完美! – Max

1
for f in file1 file2 file3; do 
    cut -f 6 $f; done | 
awk '{if ($1~/Pattern5/) {printf("\n%s\t",$1)} else {printf("%s\t",$1)} };END{print ""}' | 
tail -n +2 

「Pattern5」 0.654153736328455 0.36576227771633 0.999993466995047
「Pattern5」 0.654153736328455 0.36576227771633 0.999993466995047
「Pattern5」 0.654153736328455 0.36576227771633 0.999993466995047

(我只是使用相同的數據file1-3。) 你也可以指定輸入文件,如果他們是regularl y命名,帶有glob,例如for f in myfiles*