2017-08-02 87 views
1

我有一個文件,其中有一個記錄的條目,然後下面的行是關聯的外顯子。有時候,這可能是一個外顯子等一個後續行,有時也有「N」個外顯子等「N」後續行,像這樣:如果接下來兩行匹配,打印行+下兩行awk

1  Cufflinks  transcript  63846957  63847511 
1  Cufflinks  exon 63846957  63847511 
1  Cufflinks  transcript  63851691  63852040  
1  Cufflinks  exon 63851691  63852040 
2  Cufflinks  transcript  8442356 8443964 
2  Cufflinks  exon 8442356 8442368 
2  Cufflinks  exon 8443768 8443964 
2  Cufflinks  exon 8444000 8444578 
2  Cufflinks  transcript  8258988 8259803 
2  Cufflinks  exon 8258988 8259271 
2  Cufflinks  exon 8259370 8259803 

我想打印出的成績單和相關的外顯子線僅如果在成績單後有兩個外顯子。對於這個例子,只會提取最後三行(一個轉錄本行和兩個外顯子行)。

這怎麼用awk來完成?

回答

0

您可以保存數組中的行,然後在確定外顯子的數量後打印出來。

#!/usr/bin/awk -f 

BEGIN { 
     number_of_exons = 0; 
} 

END { 
     print_if_two_exons(); 
} 

$3 == "transcript" { 
     print_if_two_exons(); 
     transcript = $0; 
} 

$3 == "exon" { 
     exons[number_of_exons++] = $0; 
} 

function print_if_two_exons() { 
     if (transcript && number_of_exons == 2) { 
       print transcript; 
       for (i = 0; i < number_of_exons; i++) { 
         print exons[i]; 
       } 
     } 
     delete exons; 
     number_of_exons = 0; 
} 

輸出:

2  Cufflinks  transcript  8258988 8259803 
2  Cufflinks  exon 8258988 8259271 
2  Cufflinks  exon 8259370 8259803 
+0

謝謝您的回答。你介意解釋一下代碼嗎?我仍然試圖教自己bash/awk。 – zoe

+1

我試圖儘可能保持代碼的可讀性和自解釋性,但這取決於您的經驗水平。你有什麼具體的問題嗎? –

+0

我覺得我很困惑,因爲print_if_two_exons()被調用兩次?一旦END和一次$ 3 ==轉錄?我也不太明白number_of_exons是如何填充的?對不起,我幾乎是初學者。 – zoe

0
$ cat tst.awk 
/transcript/ { prt() } 
{ buf = buf $0 ORS; ++cnt } 
END { prt() } 
function prt() { 
    if (cnt == 3) { 
     printf "%s", buf 
    } 
    buf = "" 
    cnt = 0 
} 

$ awk -f tst.awk file 
2  Cufflinks  transcript  8258988 8259803 
2  Cufflinks  exon 8258988 8259271 
2  Cufflinks  exon 8259370 8259803 
0
$ cat awk-script 
function set_all(s,t,e) { 
    exon=e;tran=t;str=s 
} 
/transcript/{set_all($0,1,0)} 
/exon/{ 
    if(tran){ 
    if(exon<2) 
     set_all(str"\n"$0,tran,exon+1) 
    else 
     set_all("",0,0) 
    } else   
    set_all("",0,0) 
} 
END { 
    print str 
} 

$ awk -f awk-script file 
2  Cufflinks  transcript  8258988 8259803 
2  Cufflinks  exon 8258988 8259271 
2  Cufflinks  exon 8259370 8259803 

非常簡單的方法,我會解釋它作爲其次,

  • 設置可變exontran記錄連續顯示的數字爲exontranscript,分別爲
  • 聲明函數set_all來設置strexon值,tran
0

可以使用PCRE來做到這一點。

Demo

在紅寶石:

$ ruby -e 'buf=$<.read 
     buf.scan(/.*transcript.*\n+.*exon.*\n.*exon.*\n(?=(?:.*transcript)|\z)/) 
      .each { |m| puts m }' 
2  Cufflinks  transcript  8258988 8259803 
2  Cufflinks  exon 8258988 8259271 
2  Cufflinks  exon 8259370 8259803 

的Perl:

$ perl -0777 -lane 'while (/(.*transcript.*\n+.*exon.*\n+.*exon.*\n+)(?=(?:.*transcript)|\z)/g) {print $1;}' file 

在Python,GNU的grep類似等