簡體   English   中英

正則表達式/ Perl以匹配包含字符串的文本塊

[英]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\n[\s\S]*?(?=(?:\n\nEVENT-header|$))

您可以使用它。請參閱演示。

https://regex101.com/r/hR7tH4/3

有多種方法可以做到這一點,多行正則表達式匹配是一個很好的選擇。 如果數據文件看起來像常規文件一樣,特別是每個“記錄”都由標記“ 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM