Befehl zum Extrahieren von Daten zwischen 2 Zeilen

Befehl zum Extrahieren von Daten zwischen 2 Zeilen

Ich muss die Ausnahme und den entsprechenden Stacktrace ab einer Zeilennummer in einer Protokolldatei extrahieren. Ich kenne die Startzeilennummer des Fehlers. Wie kann ich anhand des folgenden Beispiels herausfinden, wo der Stacktrace endet? Vielen Dank für Ihre Hilfe

Beispiel
---------
2016-10-07 15:49:07,537 FEHLER Eine Ausnahme
 Stacktrace Zeile 1
 Stacktrace Zeile 2
 .
 .
 Stacktracezeile Substantiv, Neutrum—
07.10.2016 15:49:07,539 Debuggen, bla, bla, bla
07.10.2016 15:49:07,540 Debuggen, bla, bla, bla

Antwort1

Zusammenfassend möchten Sie Zeilen drucken, die mit der von Ihnen angegebenen Zeilennummer beginnen und bis unmittelbar vor die erste folgende Zeile reichen, die mit einem Datum beginnt. In Ihrem Beispiel ist die Startzeile 3. In diesem Fall:

$ awk '{if (NR==3)f=1; else if (/^[0-9-]{10} /)f=0} f{print}' trace.log
2016-10-07 15:49:07,537 ERROR Some exception
 stacktrace line 1
 stacktrace line 2
 .
 .
 stacktrace line n

Der obige Code funktioniert wie folgt:

  • if (NR==3)f=1

    Setzen Sie die Variable auf der von Ihnen angegebenen Zeilennummer fauf eins.

  • else if (/^[0-9-]{10} /)f=0

    Setzen Sie in anderen Zeilen den Wert fauf Null, wenn die Zeile mit 10 Zeichen beginnt, die aus Ziffern oder Bindestrichen bestehen, gefolgt von einem Leerzeichen. Mit anderen Worten: Setzen Sie den Wert fauf Null in der ersten Zeile, die mit etwas beginnt, das wie ein Datum aussieht.

    Bei Bedarf können wir komplexere reguläre Ausdrücke verwenden, um den Beginn eines Datums zu identifizieren. Im Folgenden ist beispielsweise erforderlich, dass die Zeile mit etwas beginnt, das wie ein Datum aussieht, gefolgt von einem Leerzeichen, gefolgt von etwas, das wie eine Uhrzeit aussieht, gefolgt von einem Komma.

    awk '{if (NR==3)f=1; else if (/^[0-9-]{10} [0-9:]{8},/)f=0} f{print}' trace.log
    

    Hier sind noch weitere Verbesserungen möglich.

  • f{print}

    Wenn fder Wert ungleich Null ist, drucken Sie die Zeile.

    Der Kürze halber könnten wir f{print}einfach durch ersetzen f. Das ist möglich, weil die Standardaktion von printverwendet wird, wenn eine Aktion nicht explizit angegeben wird.

Alternative

Einige Versionen von awk unterstützen keine Wiederholungsfaktoren wie {10}. Wenn das auf Ihrem System der Fall ist, versuchen Sie:

awk '{if (NR==3)f=1; else if (/^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] /)f=0} f{print}' trace.log

Antwort2

Vorausgesetzt, alle Stacktracezeilen beginnen mit einem Leerzeichen (Leerzeichen/Tabulator), können Sie diese [[:blank:]]am Zeilenanfang ( ) zuordnen ( ^):

grep '^[[:blank:]]' file.log

Antwort3

Wenn die zu extrahierende Spur in Zeile 2 von beginnt trace.logund ihr Ende durch eine Zeile angezeigt wird, die mit einem Datum im Format JJJJ-MM-TT beginnt (und es in der Spur keine solchen Zeilen gibt), dann

sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log

druckt jede Zeile ab Zeile 2durchLinieN+3 (die erste Zeile nach der Ablaufverfolgung, die mit einem Datum beginnt). Da Sie diese letzte Zeile nicht möchten, leiten Sie das Obige in einen Befehl um, der die letzte Zeile entfernt:

sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log | head -n -1

oder

sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log | sed '$d'

Wenn Sie nach einem Datum suchen müssenund eine Zeitund suchen Sie dann nach

^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}

verwandte Informationen