2015-07-10 196 views
0

所以我有一個看起來是這樣的一個日誌文件的文本塊:正則表達式/ Perl來匹配包含字符串

EVENT-header 
apple 
orange 
peach 
blueberry 

EVENT-header 
bike 
car 
blueberry 

EVENT-header 
reddit 
hacker news 
stack overflow 
slashdot? 
voat 

我所試圖做的是提取文本的塊(從事件 - 在下一個EVENT-header之前添加到兩個換行符的頭部)包含單詞「桃子」。

我認爲這是一個正則表達式可以解決的問題,但是我很難做出這樣的正則表達式。這是我到目前爲止:

's/EVENT-header((?!\n\n).)+peach((?!\n\n).)+\n\n/&/p' 

我不是這方面的專家。有使用正則表達式/ perl的簡單方法嗎?

回答

2

爲此,您可以輕鬆地使用段落模式使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/; 
    } 
} 
0

有多種方法可以做到這一點,用多正則表達式匹配是一個很好的候選人。如果數據文件與出現的數據文件一樣規則,特別是每個由「EVENT-header」標記分隔的「記錄」,那麼您還可以使用設置$ /(又名$ RS又名$ INPUT_RECORD_SEPARATOR)的技巧作爲這個標記然後將文件sl成一個數組。您將爲文件中的每個記錄獲取一個數組條目,然後循環訪問該數組,然後選擇與「桃子」匹配的元素並打印出包含整個記錄的數據。

例如:

#!/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"; 
    } 
} 
+1

可能是值得一提的是'chomp'刪除記錄分隔符,它可以使事情有點清潔器。例如。你可以設置'$ /'爲「\ n \ nEVENT-header \ n」,然後'chomp'將它們從塊中移出。 – Sobrique

0

鮑羅丁已經爲您的問題提供了最佳解決方案。但這裏是萬一代碼你不想用一個班輪:

#!/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 
相關問題