2016-11-28 79 views
0

在下面的awk我試圖打印$10 = reference standard$3值匹配的行。我的實際數據是幾千行tab-delimited,所以輸入和輸出都設置爲tab-delimited。謝謝 :)。awk打印行匹配並在字段中具有特定值

AWK

awk -F'\t' -v OFS='\t' 'FNR==NR{a[$0];next} $(NF-1)$NF=="referencestandard" && {A[$3];next}$3 in A in a{print}' file 
awk: cmd. line:1: FNR==NR{a[$0];next} $(NF-1)$NF=="referencestandard" && {A[$3];next}$3 in A in a{print} 
awk: cmd. line:1:              ^syntax error 

文件

#tax_id GeneID Symbol RSG LRG RNA t Protein p Category 
9606 4200 ME2 NG_016198.1  NM_002396.4  NP_002387.1  reference standard 
9606 2122 MECOM NG_028279.1  NM_004991.3  NP_004982.2  reference standard 
9606 4204 MECP2 NG_007107.2  NM_004992.3  NP_004983.1  reference standard 
9606 4204 MECP2 NG_007107.2  NM_001110792.1  NP_001104262.1  reference standard 

所需的輸出

9606 4204 MECP2 NG_007107.2  NM_004992.3  NP_004983.1  reference standard 
9606 4204 MECP2 NG_007107.2  NM_001110792.1  NP_001104262.1  reference standard 
+1

將'&&'放在'{'?此外,這些字段通過'$ NF'編號爲'$ 1'; 「$ 0」是整條線。根據顯示的數據判斷,「參考」和「標準」之間沒有標籤。 'FNR == NR'條件意味着文件被讀取,保存且不再存在;以下術語從不執行,因爲沒有第二個文件要讀取。你可以在'END'塊中完成。目前還不清楚'你的意思是'和'$ 3'值是否匹配' - 他們需要匹配什麼?你需要澄清你試圖找到的東西。一旦要求得到充分描述,就不難做到。 –

+0

「$ 3」值匹配表示它們是相同的。每個「$ 3」值可能會重複多次,但通常只有一個「參考標準」的「$ 10」值。我試圖在那些不符合標準的文件中找到那些......這就是'$ 3'值相同而$ 10'是'參考標準'的地方。謝謝 :)。 – Chris

+1

你必須更加精確。你的意思是兩個不同的行在'$ 3'中具有相同的值?不管其他領域有什麼?你想同時打印兩行?如果在$ 3中有三行具有相同的值,您想要打印3行還是3行?在你的樣本數據中,'$ 3'中的重複也會重複'$ 1'和'$ 2'(和$ 4')中的值 - 這很重要嗎? –

回答

1

對於只有幾千行,這大概是最容易處理的數據文件(我的是稱爲data)兩次 - 列表它在命令行上兩次。在第一遍中,記錄$3值的最後一個字段設置爲「參考標準」的次數記錄。在第二次,打印這些記錄與設置爲「參考標準」和$3大於1出現的計數的最後一個字段:

awk -F'\t' -v OFS='\t' \ 
    'FNR == NR && $NF == "reference standard" { a[$3]++; next } 
    a[$3] > 1 && $NF == "reference standard" { print }' data data 

對於樣本數據,我得到的輸出是:

9606 4204 MECP2 NG_007107.2  NM_004992.3  NP_004983.1  reference standard 
9606 4204 MECP2 NG_007107.2  NM_001110792.1 NP_001104262.1 reference standard 

該技術避免了將文件的整個副本保留在內存中,並避免了一些其他的簿記問題。由於你的代碼已經有了FNR==NR模因,我認爲你在考慮這些方面,即使你沒有在命令行重複文件名。

如果你能負擔得起在內存中保存整個文件(或它來自一個管道而不是一個文件,所以你不能重新掃描),可以以單道次這樣做:

awk -F'\t' -v OFS='\t' \ 
    'FNR==NR && $NF == "reference standard" { 
      index = a[$3]++; line[NR] = $0; reps[$3,index] = NR; next 
    } 
    END { for (i in a) 
       if (a[i] > 1) 
        for (j = 0; j < a[$3]; j++) 
         print line[reps[i,j]] 
    }' data 

這產生相同的輸出,當然。缺點是你有一個完整的數據集在內存中的副本,加上各種控制數組,所以它使用的內存比雙向備選更多。

+0

非常感謝,我一直在思考,但不知道如何實現它....感謝您的幫助和解釋:) – Chris

相關問題