2017-02-21 4 views
1

ich eine große Menge an langen unregelmäßigen Protokolle verfügen, die wie folgt aussehen:eine awk oder sed Druck mit einem Schlüsselwort, bis ein Ende Muster fort erreicht ist

###<date> errortext <errorcode-xxxxx> 
errortext 
errortext 
errortext 
errortext 
###<date> errortext <errorcode-yyyy> 
errortext 
errortext 
###<date> errortext <errorcode-<zzzzzzz> 
errortext 
errortext 
errortext 
errortext 
errortext 
errortext 
errortext 

etc

Die Länge ist unregelmäßig, und Fehler mit denselben Fehlercodes müssen mit grep/awk/sed oder ähnlichen Methoden gefunden werden.

Ich muss diese Dokumente nach Fehlercode aufteilen, alle Fehler eines Codes in ein Dokument drucken.

Wenn ich versuche, ein ganzes Fehlercodesegment mit einer Linie zu finden wie:

sed -n '/#</{:start /###/!{N;b start};/<errorcode-024332>/p}' file 

Das Problem mit Linien wie die oben ist, dass es nur die Zeile drucken, die die „Error-Code-024332“ enthält und nicht der ganze Fehlercode bis zum nächsten Segmentstart (in diesem Fall mit dem Trennzeichen "###").

Wie erreiche ich das?

+1

https://stackoverflow.com/questions/38972736/how-to-select-lines-between-two-patterns könnte helfen, z. B .: awk '/ Fehlercode-024332/{f = 1; drucken; next}/^ ###/{f = 0} f 'file' wird dir 'errorcode-024332' Abschnitt – Sundeep

Antwort

2

Ihr Problem tritt auf, weil sowohl #< als auch ### mit der Zeile "header" übereinstimmen, so dass Sie nur drucken und niemals eine Schleife erstellen. Sie wurden auch an den Musterpuffer angehängt, anstatt die Zeilen nacheinander zu verbrauchen, so dass der Header immer schon gefunden wurde.

Vorausgesetzt, dass Sie die „Header“ und „Errortext“ der „Error-Code-024332“ angezeigt werden sollen, ist hier, wie ich es tun würde:

sed -n '/#<.*<errorcode-024332>/{:start p;n;/###/!{b start}}' 
  1. , wenn wir die Kopfzeile entsprechend unsere Vorstellungen Fehlercode
  2. wir drucken es
  3. wir die nächste Zeile erhalten
  4. wenn die nächste Zeile nicht ### enthält, gehen wir zurück 2.
  5. zu Schritt

Ein schneller Test ich mit Beispieldaten haben:

$ echo "###<date> errortext <errorcode-xxxxx> 
errortext 
errortext 
[...] 
errortext 
errortext " | sed -n '/#<.*<errorcode-yyyy>/{:start p;n;/###/!{b start}}' 

###<date> errortext <errorcode-yyyy> 
errortext 
errortext 
+0

hinzufügen Mein Schlüsselwort als solches hinzufügen: sed -n'/#/p} gab mir das gleiche Ergebnis wie mein alter Befehl. Habe ich falsch verstanden, wo ich das hinstellen soll? – Flowdorio

+1

@Flowdorio Ich habe es bearbeitet, bitte sagen Sie mir, wenn es Ihre Frage beantwortet. – Aaron

+0

Es tut! Vielen Dank! – Flowdorio

2

können Sie awk verwenden, wie folgt aus:

awk -F'[<>-]' '/^#/{f=$(NF-1)}{print >> f; close(f)}' file.log 

Lassen Sie es mich als mehrzeilige Version erklären:

# Using this set of field delimiters it is simple to access 
# the error code in the previous last field 
BEGIN { FS="[<>-]"} 

# On lines which start with a '#' 
/^#/ { 
    # We set the output (f)ilename to the error code 
    f=$(NF-1) 
} 

# On all lines ... 
{ 
    # ... append current line to (f)ilename 
    print >> f; 

    # Make sure to close the file to avoid running out of 
    # file descriptors in case there are many different error 
    # codes. If you are not concerned about that, you may 
    # comment out this line. 
    close(f) 
} 
Verwandte Themen