如何在Perl中的两个行分隔符之间提取行?

jba*_*sta 11 string perl extract delimiter

我有一个ASCII日志文件,其中包含一些我想要提取的内容.我从来没有花时间适当地学习Perl,但我认为这是完成这项任务的好工具.

该文件的结构如下:

... 
... some garbage 
... 
... garbage START
what i want is 
on different
lines 
END 
... 
... more garbage ...
next one START 
more stuff I want, again
spread 
through 
multiple lines 
END 
...
more garbage

所以,我正在寻找一种方法来提取每个STARTEND分隔符字符串之间的行.我怎样才能做到这一点?

到目前为止,我只找到了一些关于如何使用START字符串打印行的示例,或者其他与我正在寻找的内容有些相关的文档项.

Tel*_*hus 22

你想要触发器操作符(更好地称为范围操作符) ..

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

while (<>) {
  if (/START/../END/) {
    next if /START/ || /END/;
    print;
  }
}
Run Code Online (Sandbox Code Playgroud)

将调用替换为print您实际想要做的事情(例如,将线条推入数组,编辑它,格式化,等等).我next-ing过去,实际上有线条STARTEND,但你可能不希望这种行为.有关运算符和其他有用的Perl特殊变量的讨论,请参阅此文章.

  • 威廉,用START和END打印线条.如果你不想要它们,这里是Telemachus的oneliner:perl -ne'if(/START/../END/) {print除非/ START /或/ END /}' (2认同)

bri*_*foy 5

perlfaq6的答案我怎样才能在不同线条上的两个模式之间拉出线条?


你可以使用Perl有点奇特的运算符(在perlop中记录):

perl -ne 'print if /START/ .. /END/' file1 file2 ...
Run Code Online (Sandbox Code Playgroud)

如果你想要文字而不是线条,你会使用

perl -0777 -ne 'print "$1\n" while /START(.*?)END/gs' file1 file2 ...
Run Code Online (Sandbox Code Playgroud)

但是,如果您希望嵌套出现START到END,那么您将遇到本节中有关匹配平衡文本的问题中描述的问题.

这是使用..的另一个例子:

while (<>) {
    $in_header =   1  .. /^$/;
    $in_body   = /^$/ .. eof;
# now choose between them
} continue {
    $. = 0 if eof;  # fix $.
}
Run Code Online (Sandbox Code Playgroud)