如果下两行匹配,打印行+下两行与awk

时间:2017-08-02 03:18:16

标签: awk

我有一个文件,其中包含成绩单的条目,然后以下行是关联的外显子。有时这可能是一个外显子,因此有一个后续行,有时会有'n'个外显子,所以'n'后续行就像这样:

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完成?

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分: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以设置strexontran
  • 的值

答案 3 :(得分: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等