使用Perl读取文件并提取特定行

3

我有一个文本文件,想要获取以某个模式开头并以特定模式结尾的特定行。

例如:

Text
Text
Startpattern
print this line
Print this line
print this line
Endpattern
Text
Text
Text

同时需要打印开始模式和结束模式。我的第一次尝试并不成功:

my $LOGFILE = "/var/log/logfile";
my @array;
# open the file (or die trying)

open(LOGFILE) or die("Could not open log file.");
foreach $line () {
  if($line =~  m/Sstartpattern/i){
    print $line;
    foreach $line2 () {
      if(!$line =~  m/Endpattern/i){
        print $line2;
      }
    }
  }
}
close(LOGFILE);

Thanks in advance for your help.


1
我知道你内心深处,在你写下“无法打开日志文件。”时,其实你想写的是:“无法打开$LOGFILE: $!” - William Pursell
3个回答

14
你可以使用标量范围操作符
open my $fh, "<", $file or die $!;

while (<$fh>) {
    print if /Startpattern/ .. /Endpattern/;
}

嗨,听起来不错,但我有多个具有开始和结束模式的组。 - JohnDoe
2
@测试人员:标量 .. 应该适用于文件中的任意组数。 - Eugene Yarmash

2
这个怎么样:
#!perl -w
use strict;

my $spool = 0;
my @matchingLines;

while (<DATA>) {
    if (/StartPattern/i) {
        $spool = 1;
        next;
    }
    elsif (/Endpattern/i) {
        $spool = 0;
        print map { "$_ \n" } @matchingLines;
        @matchingLines = ();
    }
    if ($spool) {
        push (@matchingLines, $_);
    }
}

__DATA__

Text
Text
Startpattern
print this line
Print this line
print this line
Endpattern
Text
Text
Text
Startpattern
print this other line
Endpattern

如果你希望打印出起始和结束模式,也可以在if语句块中添加push语句。


完美的。非常感谢。现在我只有一个问题 :-) 如何设置动态数组名称并在获取所有匹配行后打印每个数组? - JohnDoe
我对 Perl 还比较陌生,我并没有完全理解这个问题。如果您能更详细地解释一下您的需求,我可能能够提供帮助。 - Bee

1

像这样的东西?

my $LOGFILE = "/var/log/logfile";
open my $fh, "<$LOGFILE" or die("could not open log file: $!");
my $in = 0;

while(<$fh>)
{
    $in = 1 if /Startpattern/i;
    print if($in);
    $in = 0 if /Endpattern/i;
}

不幸的是,它只打印与起始模式匹配的行。我需要打印起始模式、起始模式和结束模式之间的文本以及结束模式。我有多个包含起始模式、文本、文本、文本和结束模式的组。 - JohnDoe
抱歉,我的错误。我忘记删除一行了。我该如何将这些条目分组到几个数组中? - JohnDoe
我也在做类似的东西,但是eugene-y提到的解决方案也会打印起始模式和结束模式,而我们不需要它们,如何将它们排除掉,请建议。 - XYZ_Linux

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接