2

首先,如果您觉得这是重复的,我深表歉意。我环顾四周,发现了一些非常相似的问题,但我要么迷路了,要么这不是我认为我需要的,因此无法提出正确的实现。

问题:

所以我有一个 txt 文件,其中包含由另一个脚本创建的条目(如果您可以提出更好的格式化方式,我可以编辑这些条目的生成方式):

SR4 Pool2
11/5/2012 13:45
----------
Beginning Wifi_Main().

SR4 Pool2
11/8/2012 8:45
----------
This message is a
multiline message.

SR4 Pool4
11/5/2012 14:45
----------
Beginning Wifi_Main().

SR5 Pool2
11/5/2012 13:48
----------
Beginning Wifi_Main().

我制作了一个 perl 脚本来解析文件:

#!C:\xampp-portable\perl\bin\perl.exe

use strict;
use warnings;
#use Dumper;

use CGI 'param','header';
use Template;
#use Config::Simple;

#Config::Simple->import_from('config.ini', \%cfg);

my $cgh = CGI->new;
my $logs = {};
my $key;

print "Content-type: text/html\n\n"; 

open LOG, "logs/Pool2.txt" or die $!;


while ( my $line = <LOG> ) {
    chomp($line);

}

print $logs;

close LOG;

我的目标是最终得到一个如下所示的哈希:

$logs = {
    SR4 => {
           Pool2 => {
                {
                    time => '11/5/2012 13:45',
                    msg  => 'Beginning Wifi_NDIS_Main().',
                },
                {
                    time => '11/8/2012 8:45',
                    msg  => 'This message is a multiline message.',
                },
           },
           Pool4 => {
                {
                    time => '11/5/2012 13:45',
                    msg  => 'Beginning Wifi_NDIS_Main().',
                },
           },
    },
    SR5 => {
           Pool2 => {
                {
                    time => '11/5/2012 13:45',
                    msg  => 'Beginning Wifi_NDIS_Main().',
                },
           },
    },

};

解决这个问题的最佳方法是什么?我应该更改生成日志的格式以使自己更容易吗?如果您需要更多信息,请询问。提前谢谢你。:)

4

3 回答 3

2

如果您可以将其输出为 XML,那么使用XML::Simple读取它会非常容易

于 2012-11-06T01:16:10.860 回答
2

格式没有意义。您在第三级使用了散列,但没有为值指定键。我假设它应该是一个数组。

my %logs;
{
   local $/ = "";  # "Paragraph mode"
   while (<>) {
      my @lines = split /\n/;
      my ($x, $y) = split ' ', $lines[0];
      my $time = $lines[1];
      my $msg = join ' ', @lines[3..$#lines];
      push @{ $logs{$x}{$y} }, {
         time => $time,
         msg  => $msg,
      };
   }
}

我应该更改生成日志的格式吗

您的时间戳似乎不明确。在大多数时区,一年中的一个小时会重复。

于 2012-11-06T01:45:45.737 回答
0

虽然Karthik T使用 XML 的想法是有道理的,而且我也会考虑它,但我不确定这是否是最佳途径。第一个问题是首先将它放在 XML 格式中。

第二个是 XML 格式可能不那么容易解析。当然,XML::Simple 模块会一口气读取整个内容,然后您必须自己解析 XML 数据结构。

如果您可以根据需要设置输出,请将其设置为易于解析的格式。我喜欢使用前缀数据标识符。在以下示例中,每条数据都有自己的标识符。ER:当我达到记录的结尾时,它告诉我:

DT: 11/5/2012 13:35
SR: SR4
PL: Pool2
MG: Beginning Wifi_Main().
ER:
DT: 1/8/2012 8:45
SR: SR4
PL: Pool2
MG: This message is a
MG: multiline message.
ER:

解析这个输出很简单:

my %hash;
while ( $line = <DATA> ) {
    chomp $line;
    if ( not $line eq "ER:" ) {
        my ($key, $value) = split ( ": ", $line );
        $hash{$key} .= "$value ";   #Note trailing space!
    }
    else {
        clean_up_hash ( \%hash ); #Remove trailing space on all values
        create_entry ( \%log, \%hash );
        %hash = ();
    }
}

每当我开始获得复杂的数据结构时,我都喜欢使用类,并且我可能会创建一个Local::Log类和子类来存储日志的每一层。但是,这不是绝对必要的,也不是您问题的一部分。尽管如此,我还是会使用一个create_entry子例程来保持逻辑,即找出该条目在循环中的位置。

注意:我在每条数据后附加一个空格。我这样做是为了使代码更简单,因为您的某些消息可能需要多于一行。还有其他方法可以处理这个问题,但我试图让循环尽可能干净,并尽可能少地使用if语句。

于 2012-11-06T14:01:58.170 回答