1

我有一个文件,我想获取所有以 CDS 开头的行和下面的一行。这行是这样的:

CDS             297300..298235
                      /gene="ENSBTAG00000035659"

我在你的网站上找到了这个:

open(FH,'FILE');

while ($line = <FH>) {
if ($line =~ /Pattern/) {
    print "$line";
    print scalar <FH>;
}
}

当 CDS 只是一条线时,它工作得很好。有时在我的文件中就像

CDS             join(complement(416559..416614),complement(416381..416392),
               complement(415781..416087))
               /gene="ENSBTAG00000047603"

或在 CDS 中有更多行。怎么才能只取CDS线和ID的下一行???拜托我需要你的帮忙!先感谢您。

4

2 回答 2

3

假设“下一行”总是包含/gene=,可以使用触发器运算符

while (<>) {
   print if m{^CDS} ... m{/gene=};
}

否则,您需要解析 CDS 行。计算括号可能就足够了。

my $depth = 0;
my $print_next = 0;
while (<>) {
   if (/^CDS/) {
       print;
       $depth = tr/(// - tr/)//;
       $print_next = 1;
   }
   elsif ($depth) {
       print;
       $depth += tr/(// - tr/)//;
   }
   elsif ($print_next) {
       print;
       $print_next = 0;
   }
}
于 2013-07-03T16:15:56.763 回答
0

您需要将输入分成缩进的段落。缩进段落的第一行以非空格字符开头,其余段落以空格字符开头。

尝试:

#!/usr/bin/env perl

use strict;
use warnings;

# --------------------------------------

my $input_file = shift @ARGV;
my $para = undef; # holds partial paragraphs

open my $in_fh, '<', $input_file or die "could not open $input_file: $!\n";
while( my $line = <$in_fh> ){

  # paragraphs are outdented, that is, start with a non-space character
  if( $line =~ m{ \A \S }msx ){

    # don't do if very first line of file
    if( defined $para ){

      # If paragraph starts with CDS
      if( $para =~ m{ \A CDS \b }msx ){
        process_CDS( $para );
      }

      # delete the old paragraph
      $para = undef;
    }
  }

  # add the line to the paragraph,
  $para .= $line;
}
close $in_fh or die "could not close $input_file: $!\n";

# the last paragraph is not handle inside the loop, so do it now
if( defined $para ){

  # If paragraph starts with CDS
  if( $para =~ m{ \A CDS \b }msx ){
    process_CDS( $para );
  }

}
于 2013-07-03T17:12:52.537 回答