如何在Perl中匹配一行后抓取多行?

时间:2013-05-06 02:05:37

标签: perl

我的文件如下:

1  15
2  16
3  18
4  19
5  25
6  30
7  55
8  45
9  34
10 52

如果匹配的模式在第6行中是30,我想先获取N行,并在第6行之后获取M行,例如,如果N = 3且M = 4,那么结果应该是这样的:< / p>

3  18
4  19
5  25
6  30
7  55
8  45
9  34
10 52

我是Perl的新手,任何建议都会受到赞赏。

#UPDATE 非常感谢下面这些有用的建议,我真的很感激他们。 这是我的更新代码,欢迎提出任何建议!

my $num;

while(<>)
{   
if ( /pattern/) 
{$num = $. ;}   
}

open (,"") || die ("Can't open the file");

while(<>)

{
if (  $. >= $num-N and $. <=$num+M)
{    
print OUT "$_ \r";
}
}

2 个答案:

答案 0 :(得分:1)

保持读取的最后@preceding行的数组(我称之为N)。匹配模式时,停止更新此数组并开始将行插入另一个数组(@following)。在@following包含M行之前执行此操作。

它应该看起来像这样(现在由于ikegami修复):

my $matched = 0;
my @preceding;
my @following;
while(<>){
    if ($matched){
        push ( @following, $_);
        last if @following == M;
        next;
    }
    else {
        push ( @preceding, $_);
        shift(@preceding) if @preceding > N;
    }
    $matched = 1 if /pattern/;
}

答案 1 :(得分:0)

my @lines = <>;
foreach $idx (grep { $lines[$_] =~ /pattern/ } 0..$#lines) {
    print join (map {$lines[$_]} grep { $_ >= $idx - $B && $_ <= $idx +$A } 0..$#lines)."\n";
}

您也可以使用带有-A,-B标志的GNU grep命令来实现此目的。

  -A NUM, --after-context=NUM
          Print NUM lines  of  trailing  context  after  matching  lines.
          Places  a  line  containing  --  between  contiguous  groups of
          matches.

   -B NUM, --before-context=NUM
          Print  NUM  lines  of  leading  context  before matching lines.
          Places a  line  containing  --  between  contiguous  groups  of
          matches.