如何在 Perl 中提取两个行分隔符之间的行?
我有一个 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
因此,我正在寻找一种方法来提取每个 START
和 END
分隔符字符串之间的行。 我怎样才能做到这一点?
到目前为止,我只找到了一些有关如何使用 START
字符串打印一行的示例,或与我正在寻找的内容有些相关的其他文档项目。
I have an ASCII log file with some content I would like to extract. I've never taken time to learn Perl properly, but I figure this is a good tool for this task.
The file is structured like this:
... ... 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
So, I'm looking for a way to extract the lines between each START
and END
delimiter strings.
How can I do this?
So far, I've only found some examples on how to print a line with the START
string, or other documentation items that are somewhat related with what I'm looking for.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您需要触发器运算符(也称为范围运算符)
..
将对
print
的调用替换为您实际想要执行的操作(例如,将行推入一个数组,编辑它,格式化它,等等)。 我next
- 超过了实际具有START
或END
的行,但您可能不希望出现这种行为。 有关此运算符的讨论,请参阅本文其他有用的 Perl 特殊变量。You want the flip-flop operator (also known as the range operator)
..
Replace the call to
print
with whatever you actually want to do (e.g., push the line into an array, edit it, format it, whatever). I'mnext
-ing past the lines that actually haveSTART
orEND
, but you may not want that behavior. See this article for a discussion of this operator and other useful Perl special variables.来自 perlfaq6 的回答 如何拉出本身位于不同行的两个模式之间的行?
您可以使用 Perl 有点奇特的 .. 运算符(在 perlop 中记录):
如果您想要 但是,
如果您想要嵌套出现 START 到 END,您将遇到本节中有关匹配平衡文本的问题中描述的问题。
这是使用 .. 的另一个示例:
From perlfaq6's answer to How can I pull out lines between two patterns that are themselves on different lines?
You can use Perl's somewhat exotic .. operator (documented in perlop):
If you wanted text and not lines, you would use
But if you want nested occurrences of START through END, you'll run up against the problem described in the question in this section on matching balanced text.
Here's another example of using ..:
如何在Perl 中的匹配行?
那怎么样? 其中,END 字符串是 $^,您可以将其更改为您的 END 字符串。
我也是新手,但是那里的解决方案提供了相当多的方法...让我更具体地知道您想要的与上面的链接不同的是什么。
How can I grab multiple lines after a matching line in Perl?
How's that one? In that one, the END string is $^, you can change it to your END string.
I am also a novice, but the solutions there provide quite a few methods... let me know more specifically what it is you want that differs from the above link.
下次尝试写一些代码
try to write some code next time round
忒勒马科斯答复后,事情开始倾泻而出。 这毕竟是我正在寻找的解决方案。
这对我有用,尽管代码可以被归类为丑陋; 这是因为我目前几乎是 Perl 的新手。 无论如何,
我希望它也能对其他人有益。
干杯。
After Telemachus' reply, things started pouring out. This works as the solution I'm looking at after all.
This works for me, although the code can be classified as ugly; this is because I'm currently a virtually newcomer to Perl. Anyway here goes:
I hope it benefits others as well.
Cheers.
对于来自“虚拟新人”来说还不错。 您可以做的一件事是将“$found=1”放在“if($found == 0)”块内,这样您就不会每次在 $start 和 $stop 之间执行该分配。
在我看来,另一件有点丑陋的事情是,每次输入 $start/$stop-block 时都会打开相同的文件处理程序。
这显示了一种解决方法:
Not too bad for coming from a "virtual newcommer". One thing you could do, is to put the "$found=1" inside of the "if($found == 0)" block so that you don't do that assignment every time between $start and $stop.
Another thing that is a bit ugly, in my opinion, is that you open the same filehandler each time you enter the $start/$stop-block.
This shows a way around that: