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

形式は意味がありません。第3レベルでハッシュを使用しましたが、値のキーを指定しませんでした。配列だと思います。

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,
      };
   }
}

生成されたログのフォーマットを変更する必要があります

タイムスタンプがあいまいに見えます。ほとんどのタイムゾーンでは、1年のうち1時間が繰り返されます。

于 2012-11-06T01:45:45.737 に答える
0

Karthik TがXMLを使用するという考えは理にかなっており、私もそれを検討しますが、これが最善のルートかどうかはわかりません。最初の問題は、そもそもXML形式にすることです。

2つ目は、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 に答える