2010-05-14 91 views
0

我有一個應用程序每5秒產生一個日誌。日誌格式如下。如何在Perl中讀取持續更新的日誌文件?

11:13:49.250,interface,0,RX,0 
11:13:49.250,interface,0,TX,0 
11:13:49.250,interface,1,close,0 
11:13:49.250,interface,4,error,593 
11:13:49.250,interface,4,idle,2994215 
and so on for other interfaces... 

我正在努力將這些轉換爲下面的CSV格式:

Time,interface.RX,interface.TX,interface.close.... 
11:13:49,0,0,0,.... 

這麼簡單的,但現在的問題是,我必須儘快獲得CSV格式的數據線上,即日誌文件更新的CSV也應該更新。

我試圖讀取輸出,使標題是:

#!/usr/bin/perl -w 
use strict; 

use File::Tail; 
my $head=["Time"]; 
my $pos={}; 
my $last_pos=0; 
my $current_event=[]; 

my $events=[]; 

my $file = shift; 
$file = File::Tail->new($file); 

while(defined($_=$file->read)) { 
    next if $_ =~ some filters; 

    my ($time,$interface,$count,$eve,$value) = split /[,\n]/, $_; 
    my $key = $interface.".".$eve; 

    if (not defined $pos->{$eve_key}) { 
      $last_pos+=1; 
      $pos->{$eve_key}=$last_pos; 
      push @$head,$eve; 
     } 
     print join(",", @$head) . "\n"; 
} 

有沒有辦法做到這一點使用Perl?

+2

你的代碼有什麼問題?你可能需要打開一個輸出文件來追加讀取循環的每一次迭代? – runrig 2010-05-14 15:18:12

+0

具體問題是什麼?你能把它簡化爲File :: Tail或程序的其他部分嗎? – 2010-05-14 23:26:05

回答

2

模塊Text::CSV將允許您讀取和寫入CSV格式的文件。如果安裝了Text::CSV,它將在內部使用Text::CSV_XS,否則將回退到使用Text::CSV_PP(感謝Brad Gilbert改進此解釋)。

將相關的行分組在一起是你必須做的事;從你的例子中可以看出來源日期的來源。

確保CSV輸出更新主要是確保輸出文件行被緩衝的問題。


當大衛中號建議,也許你應該看看File::Tail模塊來處理這個問題的連續讀取方面。這應該允許您不斷從輸入日誌文件中讀取數據。

然後,您可以使用Text :: CSV中的'parse'方法分割讀取行,使用'print'方法來格式化輸出。如何結合來自各種輸入行的信息來創建輸出行對我而言是個謎 - 我無法從您給出的示例中看出邏輯如何工作。但是,我假設你知道你需要做什麼,這些工具將爲你提供處理數據所需的機制。

沒有人可以做更多的東西餵你的答案。你將不得不爲自己做一些思考。您將擁有一個可以通過File :: Tail連續讀取的文件句柄;您將擁有一個用於讀取數據行的CSV結構;你可能會有另一個CSV結構的書面輸出;您將擁有一個輸出文件句柄,確保您在每次寫入時都會刷新。連接這些點現在是你的問題。

+0

感謝喬納森,但我的問題是如何讀取和轉換日誌文件中持續更新的數據。你能否給我建議任何代碼來做到這一點。 – Space 2010-05-14 13:28:52

+1

@Octopus:所以你的問題不是關於CSV解析,而是關於不斷更新基於改變輸入的文件?這個問題不是很清楚。 – Ether 2010-05-14 16:26:49

+0

如果你的問題是不斷閱讀一個日誌文件,你應該問這個問題,而不是躲在所有的CSV文件後面。 :) – 2010-05-14 23:18:23