如何在Perl中打印匹配的行和接下来的三行?

时间:2009-06-12 21:52:00

标签: perl

我需要搜索一个模式,然后将该行以及接下来的3行写入文件(FILE)。这是一个正确的方法吗?感谢。

print FILE if /^abc/;
$n=3 if /^abc/;
print FILE if ($n-- > 0);

6 个答案:

答案 0 :(得分:5)

我喜欢..运营商:

perl -ne 'print if (/abc/ and $n=3) .. not $n--'

但是您没有描述如果在以下三行中重复abc模式会发生什么。如果你想重启计数器,如果用双重打印修复一个小错误,你的方法是正确的。

perl -ne'$n=4 if/abc/;print if$n-->0'

答案 1 :(得分:5)

您可以将其简化为使用标志变量来知道是否应该打印一行:

while( <$input> ) {
    $n=4 if /^abc/; 
    print FILE if ($n-- > 0);
    }

除了简化之外,它还解决了一个问题:在你的版本中,abc字符串将被打印两次。

答案 2 :(得分:5)

这是命令行grep(1)的一个特性。无需编程:

grep abc --after-context=3

你在上下文组之间得到' - '行,但这些行很容易剥离。在Perl中完成整个事情也很容易。 :)

当以下三行中的一行还包含您正在寻找的模式时,您将要执行的操作。 grep(1)将重置计数器并保持打印行。

答案 3 :(得分:2)

无需将文件粘贴在一起或尝试在一行中编写代码:

#!/usr/bin/perl
use strict;
use warnings;

while ( my $line = <DATA> ) {
    if ( $line =~ /^abc/ ) {
        print $line;
        print scalar <DATA> for 1 .. 3;
    }
}
__DATA__
x
y
z
abc
1
2
3
4
5
6

答案 4 :(得分:0)

另一种可能的解决方案......

#!/usr/bin/perl

use strict;

my $count = 0;
while (<DATA>) {
    $count = 1 if /abc/;
    if ($count >= 1 and $count <= 3) {
        next if /abc/;
        print;
        $count++;
    }
}

__DATA__
test
alpha
abc
1
234123
new_Data
test

答案 5 :(得分:-3)

我宁愿采取一些额外的代码行,使一切更清晰。这样的事情应该有效:

my $count = 0;
while ( my $line = pop @file ) {
   if ( /^abc/ ) {
      $count = 4;
   }

   if ( $count > 0 ) {
       print FILE $line;
       $count--;
   }
}

编辑以回复评论:

  • 错过正则表达式是一个错误,现在已修复。
  • 打印换行符当然是可选的,就像啜饮文件一样。不同的人有不同的风格,这是人们喜欢Perl的事情之一!