2017-06-29 9 views
-1

私はlog4netログファイルを処理するperlスクリプトを書こうとしています。ログファイル内のフィールドは、セミコロンで区切られています。私の最終目標は、各フィールドをキャプチャし、mysqlテーブルを作成することです。perlを使って複数の行に分割する

は通常、私は、これらが処理しやすい

DEBUG;2017-06-13T03:56:38,316-05:00;2017-06-13 08:56:38,316;79ab0b95-7f58- 
44a8-a2c6-1f8feba1d72d;(null);WorkerStartup 1;"Starting services." 

(単一ライン上のすべての)このような小さなを見てラインを持っています。セミコロンで分割して、必要な情報を得ることができます。

しかし、たまには、特にスタックトレースがある場合、末尾の「メッセージ」フィールドが複数の行にまたがる場合があります。私は単一の列としてメッセージ全体をキャプチャしたいと思います。次の行は、通常のようになりますので、私は、セミコロンで分割を使用することはできません。

at some.random.classname 
at another.classname 
... 

誰かがどのようにこの問題を解決するためにいくつかのヒントを与えることはできますか?

+0

del imiterをセットし、 '$ /'をセットします。 – Sobrique

+0

詳しいことはありますか?よく分からない? –

+0

ログエントリの*開始*を特定する方法を知っています。この情報を使用して、別のログエントリにヒットするまで次の行を蓄積します。 –

答えて

0

後の溶液は、現場で」の数が奇数"この条件数は、フィールドが完了していないであることを示すことができる他によって変更されてもよい、偶数($p=~y/"//%2)であることを使用する。 7に固定されて分割される列の数を(最後のフィールドで;を可能にする)および実施例@array = map {s/;$//} $p=~/\G(?:"[^"]*"|[^;])*;/g;ために変更することができる。 ファイルは、ライン毎に読み取られるが、それは最後の行は、ENDブロックで処理される前のラインを記憶するために$p可変完全だときにラインがsub process処理される。

perl -ne ' 
    sub process { 
     @array = split /;/,$p,7; 
     # do something with array 
     print ((join "\n---\n", @array),"\n"); 
    } 
    if ($p=~y/"//%2) { 
     $p.=$_; 
     next; 
    } 
    process; 
    $p=$_; 
    END{process} 
' < logfile.txt 
関連する問題