[英]Regex/Perl to match blocks of text that contain a string
所以我有一個日志文件,看起來像這樣:
EVENT-header
apple
orange
peach
blueberry
EVENT-header
bike
car
blueberry
EVENT-header
reddit
hacker news
stack overflow
slashdot?
voat
我想做的是提取包含單詞“ peach”的文本塊(從EVENT標頭到下一個EVENT標頭之前的兩個換行符)。
我認為這是正則表達式可以解決的問題,但是我在制作能夠做到這一點的正則表達式時遇到了麻煩。 到目前為止,這是我提出的內容:
's/EVENT-header((?!\n\n).)+peach((?!\n\n).)+\n\n/&/p'
我不是這個專家。 是否有使用regex / perl的簡單方法?
您可以使用段落模式輕松完成此操作,該模式使perl讀取由空白行分隔的文本塊
perl -00 -ne'print if /peach/' logfile.log
如果您喜歡完整的程序文件,則它看起來像這樣
use strict;
use warnings;
open my $fh, '<', 'logfile.log' or die $!;
{
local $/ = '';
while ( <$fh> ) {
print if /peach/;
}
}
有多種方法可以做到這一點,多行正則表達式匹配是一個很好的選擇。 如果數據文件看起來像常規文件一樣,特別是每個“記錄”都由標記“ EVENT-header”隔開,那么您還可以使用將$ /(aka $ RS aka $ INPUT_RECORD_SEPARATOR)設置為標記的技巧然后將文件插入到數組中。 您將為文件中的每個記錄獲取一個數組條目,然后遍歷數組,選擇與“桃子”匹配的元素並打印出整個包含的記錄就很簡單了。
例如:
#!/usr/bin/perl -w
use strict;
$/='EVENT-header';
my (@entries, $entry);
my $infile = 'data.txt';
open(IN, "<$infile") or die "Aaargh: $^E\n";
@entries = <IN>;
chomp @entries;
close(IN);
foreach $entry (@entries)
{
if ($entry =~ m/peach/)
{
print "matching entry: $entry\n";
}
}
Borodin已經為您的問題提供了最佳解決方案。 但是如果您不想使用一個襯板,這里是一個代碼:
#!/usr/bin/perl
use warnings;
use strict;
local $/ = ""; #to enable paragraph mode
open my $fh, "<", "input.log" or die "Unable to open file: $!";
while (my $line = <$fh>)
{
chomp $line;
if ($line =~ m/peach/)
{
print $line, "\n";
}
}
輸出:
EVENT-header
apple
orange
peach
blueberry
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.