2016-08-23 78 views
0

我需要將一個文件中的單個列條目與第二個文件中的列條目匹配,貝殼)。我使用的awk命令只匹配列表的第一個單詞,並且不掃描列字段中的整個列表。將一個文件中的單列條目匹配到第二個文件中的列條目,該列條目由一個列表組成

文件1是這樣的:

chr1:725751 LOC100288069   
rs3131980 LOC100288069   
rs28830877 LINC01128  
rs28873693 LINC01128  
rs34221207 ATP4A  

文件2如下所示:

Annotation Total Genes With Ann Your Genes With Ann) Your Genes No Ann) Genome With Ann) Genome No Ann) ln 
1 path hsa00190  Oxidative phosphorylation 55 55 1861 75 1139 5.9 9.64 0 0 ATP12A ATP4A ATP5A1 ATP5E ATP5F1 ATP5G1 ATP5G2 ATP5G3 ATP5J ATP5O ATP6V0A1 ATP6V0A4 ATP6V0D2 ATP6V1A ATP6V1C1 ATP6V1C2 ATP6V1D ATP6V1E1 ATP6V1E2 ATP6V1G3 ATP6V1H COX10 COX17 COX4I1 COX4I2 COX5A COX6B1 COX6C COX7A1 COX7A2 COX7A2L COX7C COX8A NDUFA5 NDUFA9 NDUFB3 NDUFB4 NDUFB5 NDUFB6 NDUFS1 NDUFS3 NDUFS4 NDUFS5 NDUFS6 NDUFS8 NDUFV1 NDUFV3 PP PPA2 SDHA SDHD TCIRG1 UQCRC2 UQCRFS1 UQCRH 

預期輸出:

rs34221207 ATP4A hsa00190 

(請原諒的格式 - 所有列製表符分隔,直到基因名稱列14美元,稱爲Genome ...)

我的命令是這樣的:

awk 'NR==FNR{a[$14]=$3; next}a[$2]{print $0 "\t" a[$2]}' file2 file 1 

所有幫助將非常感激!

+0

這兩個文件有匹配嗎? –

+0

基於這兩個文件的預期輸出是什麼? – oliv

+0

我編輯了你的'file2',使它包含字符串'LOC100288069'作爲第14個字段,並且我運行了'awk'代碼......它按預期工作。很明顯,使用'file1'和'file2'的例子,你的'awk'代碼不能打印任何東西。 – Jdamian

回答

1

你需要處理的其他命令文件,並遍歷列表:

awk 'NR==FNR{a[$2]=$1; next} {for(i=15;i<=NF;++i)if(a[$i]){print a[$i] "\t" $i "\t" $3}}' file1 file2 

說明:

NR是一個全球性的「備案號」反了awk遞增讀取每一行每個文件。 FNR是每個文件的「記錄號」,awk在每個文件的第一行重置爲1。因此NR==FNR條件對於第一個文件中的行是真實的,對於後續文件中的行是false。這是一個awk習慣用於挑選第一個文件信息。在這種情況下,a[$2]=$1存儲由第二個字段文本鍵入的第一個字段文本。 next告訴awk在當前行停止短路並讀取並繼續正常處理下一行。在這樣的第一個動作子句末尾的next在功能上與其餘代碼中的ELSE條件相同,如果awk具有這樣的語法(它沒有):NR==FNR{a[$2]=$1} ELSE {for...NR==FNR{a[$2]=$1}NR!=FNR{for...更清晰,只有稍微省時的效率。

現在到第二個動作條款。前面沒有任何條件意味着awk會爲沒有被前面的next短路的每一行執行它,也就是說,只有在這種情況下,第一個文件2以外的文件中的所有行。你的file2有一個從字段#15開始並延伸到最後一個字段的潛在密鑰列表。最後一個字段編號的awk內置變量是NF(字段數)。 for循環是非常明顯的,然後只循環這些字段數字。對於i中的每一個數字,我們想知道該字段$i中的文本是否是第一個文件中的已知密鑰 - 設置了a[$i],即,計算結果爲非空(非錯誤)字符串。如果是這樣,那麼我們在a[$i]中有我們的file1第一個字段,我們的匹配file1第二個字段在$i,我們的file2字段在$3(當前file2第三個字段的文本)中。將它們打印爲製表符分隔。 next這裏是一個只有效率的度量,一旦我們找到匹配就停止對file2記錄的所有處理。如果您的file2密鑰列表可能包含重複項,並且您希望重複輸出行(如果這樣的重複項匹配),那麼您必須刪除最後一個next

事實上,現在我再次看,你可能確實想找到任何多個匹配,即使在非重複,所以我已經從代碼中刪除第二個next

+0

note'print a「\ t」b'等可以用awk -v OFS =「,」'{print a,b}'來表示。也就是說,使用'print'設置OFS會更好。 – fedorqui

+1

請注意接下來是在裏面。也許休息會更直觀。 –

+0

謝謝!我不熟悉編碼,你會介意解釋你的命令嗎? – Hannah6746576

相關問題