2014-04-07 34 views
1

假設我有一個日誌文件,其中包含描述某些事件的行。例如: -在日誌文件中搜索相關事件

15.03.2014 (14:23) Thing #25 deleted, user @david, session #45 
15.03.2014 (15:00) Thing #26 created, user @alex, session #54 
... 

我可以很容易地提取使用grep獨立的事件 - 它工作得很好,即使我不知道所有有關事件的信息。

但我想進一步調查相關事件。考慮在日誌下面幾行:

15.03.2014 (14:23) Thing #25 created, user @david, session #45 
... 
17.03.2014 (15:00) Thing #25 deleted, user @david, session #54 

我想搜索Thing #X created, user @Y, session #Z事件只有當它們被Thing #X deleted, user @Y, session #M事件,其中M和Z是不同的成功。

當然,我可以在5-10行代碼中執行此操作:搜索第一類事件,取所有後續行,搜索第二類事件,過濾器。

但也許有一些工具,我會重新發明輪子?

回答

1

Perl是這幾類任務的一個非常強大的工具,並且可以用一行代碼處理它,像這樣:

cat txt | perl -n -e 'if (m^Thing #(\d+).*? (created|deleted).*? user @(\S+),.*? session #(\d+)^) { my $id = "$3.$1"; if ($2 eq "created") { @db{$id} = [$4,$_] } else { if (exists($db{$id}) && $db{$id}[0] != $4) { print $db{$id}[1]."$_" } delete @db{$id} } }' 

這是同樣的事情作爲一個shell腳本,爲了便於閱讀:

#!/usr/bin/perl 

while (<>) { 
    if (m^Thing #(\d+).*? (created|deleted).*? user @(\S+),.*? session #(\d+)^) { 
    my $id = "$3.$1"; 
    if ($2 eq "created") { 
     @db{$id} = [$4,$_] 
    } else { 
     if (exists($db{$id}) && $db{$id}[0] != $4) { 
      print $db{$id}[1]."$_" 
     } 
     delete @db{$id}; 
    } 
    } 
} 

這將打印出該商品的特定用戶創建和銷燬一個特定的事物有不同的會話ID創建/銷燬線對。

請注意,腳本假定'Thing'標識符是用戶特定的,並將一個用戶創建Thing X和另一個用戶將Thing X作爲單獨事物銷燬的情況(如果這不是真的,並且用戶共享東西,則將$ id更改爲「$ 1」)。它還假定每次創建時東西最多被銷燬一次(如果每次創建可能有多次刪除,請刪除刪除行)。顯然,我沒有實際的輸入文件,因此您可能需要調整regexp以匹配實際的格式。

這種方法可能比在OP中建議的執行多個搜索要好得多,因爲它可以在沒有臨時文件的情況下一次性完成所有操作,因此它對於非常大的日誌文件可能更有效/適用。內存利用率隨着任何點上的「事物」數量而變化,所以應該合理,除非你的日誌有很多很長壽的東西。

+0

謝謝!這是一個好方法,並在O(n)中完成這項工作。但是我想知道是否有工具可以實現這種算法,或者是設計用於處理這種「查詢」的工具。 – madfriend

+0

@madfriend - Perl是最初專爲處理這種類型的文本處理而設計的工具。 「查詢」界面恰好看起來有點像命令式程序:-) –