打印行+;如果下两行匹配,则下两行使用awk

打印行+;如果下两行匹配,则下两行使用awk,awk,Awk,我有一个文件,其中有一个转录本条目,下面的几行是相关的外显子。有时这可能是一个外显子和一个后续行,有时有'n'外显子和'n'后续行,如: 1 Cufflinks transcript 63846957 63847511 1 Cufflinks exon 63846957 63847511 1 Cufflinks transcript 63851691 63

我有一个文件,其中有一个转录本条目,下面的几行是相关的外显子。有时这可能是一个外显子和一个后续行,有时有'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实现这一点?

您可以将行保存在数组中,然后在确定外显子的数量后打印它们

#!/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;
}

您可以将行保存在数组中,然后在确定外显子数量后打印它们

#!/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;
}
$cat awk脚本
功能集\u全部(s、t、e){
外显子=e;转录=t;str=s
}
/成绩单/{set_all($0,1,0)}
/外显子/{
if(tran){
如果(外显子
$cat awk脚本
功能集\u全部(s、t、e){
外显子=e;转录=t;str=s
}
/成绩单/{set_all($0,1,0)}
/外显子/{
if(tran){

如果(外显子你可以用PCRE来做这件事

在ruby中:

$ 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

与Python、GNU grep等类似,您可以使用PCRE来实现这一点

在ruby中:

$ 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

与Python、GNU grep等类似。谢谢你的回答。你介意解释一下代码吗?我仍在尝试自学bash/awk。我试图让代码尽可能可读和自解释,但这取决于你的经验水平。你有什么具体问题吗?我想我很困惑()被调用两次?一次在结束后,一次在$3==转录本时?我也不太明白外显子的数量是如何填充的?对不起,我基本上是一个初学者。对不起,混淆了。问题是,你不知道有多少外显子,直到你读过它们之后。在外显子块之外是什么?下一个转录行,还是不因此,如果两个外显子
,两者都应该触发对
print\u的调用。至于
外显子的数量
,它是通过以下语句实现的:
外显子[外显子的数量+++]=$0;
谢谢你的回答。你介意解释一下代码吗?我仍在努力自学bash/awk。我试图让代码尽可能可读和自解释,但这取决于你的经验水平。你有什么具体的问题吗?我想我很困惑,就像打印两个外显子一样()被调用两次?一次在结束后,一次在$3==转录本时?我也不太明白外显子的数量是如何填充的?对不起,我基本上是一个初学者。对不起,混淆了。问题是,你不知道有多少外显子,直到你读过它们之后。在外显子块之外是什么?下一个转录行,还是不因此,如果两个外显子
,两者都应该触发对
print\u的调用。至于
外显子的数量
,它是通过以下语句实现的:
外显子[number\u of_exons++]=$0;
$ 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 -0777 -lane 'while (/(.*transcript.*\n+.*exon.*\n+.*exon.*\n+)(?=(?:.*transcript)|\z)/g) {print $1;}' file