2010-05-14 89 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