如何从Perl文件中选择特定行

时间:2013-07-03 15:44:50

标签: perl

我有一个文件,我想把所有以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的下一行??? 拜托我需要你的帮忙! 提前谢谢。

2 个答案:

答案 0 :(得分:3)

假设“下一行”始终包含/gene=,可以使用触发器operator

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

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

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;
   }
}

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

}