2017-06-29 3 views
-1

Ich versuche, ein Perl-Skript zu schreiben, um eine log4net-Protokolldatei zu verarbeiten. Die Felder in der Protokolldatei sind durch ein Semikolon getrennt. Mein Endziel ist es, jedes Feld zu erfassen und eine MySQL-Tabelle zu füllen.Verwenden von Perl, um über mehrere Zeilen zu teilen

Normalerweise habe ich Linien, die ein wenig wie folgt aus (alle in einer einzigen Zeile) aussehen

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." 

Diese sind leicht zu verarbeiten. Ich kann einfach durch Semikolon teilen, um die Informationen zu bekommen, die ich brauche.

Gelegentlich kann sich das Feld "Nachricht" am Ende jedoch über mehrere Zeilen erstrecken, insbesondere wenn eine Stapelverfolgung vorhanden ist. Ich möchte die gesamte Nachricht als eine einzige Spalte erfassen. Ich kann nicht gespalten durch Semikolon verwenden, da die nächsten Zeilen typischerweise aussehen würde:

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

Kann jemand ein paar Tipps geben, wie dieses Problem zu lösen?

+0

Suchen Sie nach einem del imiter und setze '$ /'. – Sobrique

+0

Könnten Sie näher ausführen? Nicht sicher was du meinst? –

+0

Sie wissen, wie Sie den * Start * eines Protokolleintrags identifizieren. Verwenden Sie diese Informationen, um weitere Zeilen zu sammeln, bis Sie einen anderen Protokolleintrag treffen. –

Antwort

0

Die folgende Lösung verwendet, dass die Zahl der "in einem Feld sogar ($p=~y/"//%2) ist, diese Bedingung Anzahl der " ungerade von anderen geändert werden kann, dass das Feld nicht vollständig zeigen kann, ist. Die Anzahl der Spalten aufgeteilt ist 7 fixiert (; in letztem Feld ermöglichen) und kann @array = map {s/;$//} $p=~/\G(?:"[^"]*"|[^;])*;/g; beispielsweise geändert werden. die Datei gelesen wird Zeile für Zeile, sondern eine Linie sub process verarbeitet, wenn es vollständig $p Variable die vorherige Zeile der letzte Zeile verarbeitet wird in END-Block zu speichern.

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 
Verwandte Themen