2010-12-20 73 views
0

我有一個大文件,我只需要提取某些信息。我在網上找到了很多例子,但我無法爲我的特定實例工作。我有文件data.log(如下),並且需要將所有Stats1計數器(包括上面的數據)取出。這些統計信息有多個實例。我似乎無法得到一個正則表達式來匹配日期和Stats1,然後讀取所有內容,直到三/ n/n/n的....任何幫助非常感謝!在某些行之間讀取

# DATA FILE 

Dec 8 20:00:00 
Stats1 
    counter1:  123 
    counter2:  456 
    counter3:  789 



Dec 8 21:00:00 
Stats2 
    counter4:  123 
    counter5:  456 
    counter6:  789 



Dec 8 21:00:00 
Stats1 
    counter1:  123 
    counter2:  456 
    counter3:  789 



Dec 8 21:00:00 
Stats2 
    counter4:  123 
    counter5:  456 
    counter6:  789 
+3

到目前爲止你有什麼?問題的哪一部分給你帶來麻煩? – Quentin 2010-12-20 18:09:49

回答

0

Edit4:這些意見,這裏是希望最終版本:

use strict; 
use warnings; 
use 5.010; 
use Data::Dumper; 

my %counter_vals; 

{ 
    local $/ = "\n\n\n"; 

    while (<DATA>) { 
     my ($date) = /(
        \p{L}{3} 
        \s+ 
        (?:3[0-1]|[1-2][0-9]|[1-9])) 
         .*? 
        Stats1/msxg or next; 
     my @counter_vals = /counter[0-9]+:\s+([0-9]+)/g; 
     push @{$counter_vals{$date}}, @counter_vals; 
    } 
} 
say Dumper \%counter_vals; 
+0

請將您的所有編輯調整爲一個解決方案,刪除非工作代碼片段。 – marcog 2010-12-20 20:53:41

+0

他們工作得很好,只是他們沒有做OP的想法:p 但是k。 – Hugmeir 2010-12-20 20:58:49

0

我想,這達到你想要

/(.+)\nStats1(?:\n.+){3})/g 

什麼它下面的兩個日期相匹配:Dec 8 20:00:00Dec 8 21:00:00

+0

...假設您已將整個文檔放入'$ _' – mob 2010-12-20 19:30:50

+0

對不起,我應該已經更清楚了。在我的腦海裏,我確切地知道我的意思,但現在我讀了它... – Lozwell 2010-12-20 20:06:52

+0

對不起,我應該更清楚。在我看來,我確切地說明了我的意思,但現在我讀了它......我只想拉動Date(上面的Stats1),Stats1 Heading和所有Stats1計數器,而不是任何Stats2信息。 \ n \ n \ n是每次輸入後的三個新行。 – Lozwell 2010-12-20 20:15:33

3

嘗試閱讀段落模式:

local $/ = ""; 
while (<>) { 
    print "paragraph: $_"; 
} 

我離開搞清楚哪些段落和你想要處理什麼。

輸出爲您的樣品數據:

paragraph: # DATA FILE 

paragraph: Dec 8 20:00:00 
Stats1 
    counter1:  123 
    counter2:  456 
    counter3:  789 

paragraph: Dec 8 21:00:00 
Stats2 
    counter4:  123 
    counter5:  456 
    counter6:  789 

paragraph: Dec 8 21:00:00 
Stats1 
    counter1:  123 
    counter2:  456 
    counter3:  789 

paragraph: Dec 8 21:00:00 
Stats2 
    counter4:  123 
    counter5:  456 
    counter6:  789 
0

說實話,「最好」的解決方案取決於您的文件。例如:

  • 如果該文件是巨大的,通過<在啜這一切>或$ _也許並不明智,而如果它的「小」,這將是罰款。
  • 該文件是否具有與所示樣本一樣的常規結構?在該片段中,塊按重複計劃進行:Stats1塊位於第3,19,35,...,3 + 16n行,並以「7 + 16n」結尾。所以它可能是因爲讀文件中,只打印行,如果行號爲3和

在樂觀假設該文件是結構良好間7模16 ,它可能是那樣簡單這樣簡單:

open(IN, "inp.txt") or die; 
while (my $line = <IN>) 
{ 
    chomp $line; 
    if (($. % 16 >= 3) && 
     ($. % 16 <= 7) ) 
    { 
    print "$line\n"; 
    } 
} 
close(IN); 
0

這裏是一個辦法做到這一點:

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

local $/ = "\n\n\n"; 
while (<DATA>) { 
    print if/Stats1/; 
} 

__DATA__ 
Dec 8 20:00:00 
Stats1 
    counter1:  123 
    counter2:  456 
    counter3:  789 



Dec 8 21:00:00 
Stats2 
    counter4:  123 
    counter5:  456 
    counter6:  789 



Dec 8 21:00:00 
Stats1 
    counter1:  123 
    counter2:  456 
    counter3:  789 



Dec 8 21:00:00 
Stats2 
    counter4:  123 
    counter5:  456 
    counter6:  789 

輸出:

Dec 8 20:00:00 
Stats1 
    counter1:  123 
    counter2:  456 
    counter3:  789 



Dec 8 21:00:00 
Stats1 
    counter1:  123 
    counter2:  456 
    counter3:  789