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

Dir*_*irk 11 perl

我在Perl中逐行解析一个大文件(以\n结尾),但当我到达某个关键字时,说"TARGET",我需要抓住TARGET和下一个完全空行之间的所有行.

所以,给定一个文件的片段:

第1
行第2
行第3
行第4行目标
第5行抓住此行
第6行抓住此行
\n

它应该成为:
第4行目标
线5抓住这条
线第6行抓住这条线

我遇到麻烦的原因是我已经逐行浏览了这个文件; 如何在解析过程中途改变我划分的内容?

dav*_*420 23

你想要这样的东西:

my @grabbed;
while (<FILE>) {
    if (/TARGET/) {
        push @grabbed, $_;
        while (<FILE>) {
            last if /^$/;
            push @grabbed, $_;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果句柄没有指向实际的文件,而是指向像STDIN这样的东西,你可以获得内部同时获得一个eof并终​​止然后外部继续读取直到*它*得到一个eof.尝试使用:perl -wle'print"read a"; while(<>){print"read b"; while(<>){print"read b"} print"read a"}' (2认同)

Gre*_*con 14

范围内操作,非常适合这种任务:

$ cat try
#! /usr/bin/perl

while (<DATA>) {
  print if /\btarget\b/i .. /^\s*$/
}

__DATA__
Line 1
Line 2
Line 3
Line 4 Target
Line 5 Grab this line
Line 6 Grab this line

Nope
Line 7 Target
Linu 8 Yep

Nope again

$ ./try
Line 4 Target
Line 5 Grab this line
Line 6 Grab this line

Line 7 Target
Linu 8 Yep
Run Code Online (Sandbox Code Playgroud)


mir*_*rod 10

简短的回答:perl中的行分隔符是$/,所以当你点击TARGET时,你可以设置$/"\n\n",读取下一个"行",然后将其设置回"\n"...etvoilà!

现在为更长的一个:如果你使用English模块(它为Perl的所有魔术变量提供合理的名称,那么$/被调用$RS$INPUT_RECORD_SEPARATOR.如果你使用IO::Handle,那么IO::Handle->input_record_separator( "\n\n")将工作.

如果您将此作为更大代码的一部分,请不要忘记本地化(local $/;在适当的范围内使用)或设置回$/其原始值"\n".