
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
f
auf eins.else if (/^[0-9-]{10} /)f=0
Setzen Sie in anderen Zeilen den Wert
f
auf Null, wenn die Zeile mit 10 Zeichen beginnt, die aus Ziffern oder Bindestrichen bestehen, gefolgt von einem Leerzeichen. Mit anderen Worten: Setzen Sie den Wertf
auf 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
f
der Wert ungleich Null ist, drucken Sie die Zeile.Der Kürze halber könnten wir
f{print}
einfach durch ersetzenf
. Das ist möglich, weil die Standardaktion vonprint
verwendet 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.log
und 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}