Ich möchte alle Protokolle zwischen zwei Zeitstempeln extrahieren. Einige Zeilen haben möglicherweise keinen Zeitstempel, aber ich möchte diese Zeilen auch. Kurz gesagt, ich möchte jede Zeile, die unter zwei Zeitstempel fällt. Meine Protokollstruktur sieht folgendermaßen aus:
[2014-04-07 23:59:58] CheckForCallAction [ERROR] Exception caught in +CheckForCallAction :: null
--Checking user--
Post
[2014-04-08 00:00:03] MobileAppRequestFilter [DEBUG] Action requested checkforcall
Angenommen, ich möchte alles zwischen 2014-04-07 23:00
extrahieren und 2014-04-08 02:00
.
Bitte beachten Sie, dass der Startzeitstempel oder Endzeitstempel möglicherweise nicht im Protokoll vorhanden ist, aber ich möchte jede Zeile zwischen diesen beiden Zeitstempeln.
Akzeptierte Antwort:
Sie können awk
verwenden dazu:
$ awk -F'[]]|[[]'
'$0 ~ /^[/ && $2 >= "2014-04-07 23:00" { p=1 }
$0 ~ /^[/ && $2 >= "2014-04-08 02:00" { p=0 }
p { print $0 }' log
Wo:
-F
gibt die Zeichen[
an und]
als Feldtrenner mit einem regulären Ausdruck$0
verweist auf eine komplette Zeile$2
verweist auf das Datumsfeldp
wird als boolesche Variable verwendet, die das eigentliche Drucken überwacht$0 ~ /regex/
ist wahr, wenn Regex mit$0
übereinstimmt>=
wird zum lexikographischen Vergleich von Strings verwendet (entspricht z. B.strcmp()
)
Variationen
Die obige Befehlszeile implementiert den rechtsoffenen Zeitintervallabgleich. Um die Semantik geschlossener Intervalle zu erhalten, erhöhen Sie einfach Ihr richtiges Datum, z. B.:
$ awk -F'[]]|[[]'
'$0 ~ /^[/ && $2 >= "2014-04-07 23:00" { p=1 }
$0 ~ /^[/ && $2 >= "2014-04-08 02:00:01" { p=0 }
p { print $0 }' log
Falls Sie Zeitstempel in einem anderen Format abgleichen möchten, müssen Sie den $0 ~ /^[/
ändern Unterausdruck. Beachten Sie, dass Zeilen ohne Zeitstempel von der Druck-Ein/Aus-Logik früher ignoriert wurden.
Zum Beispiel für ein Zeitstempelformat wie YYYY-MM-DD HH24:MI:SS
(ohne []
geschweiften Klammern) könnten Sie den Befehl wie folgt ändern:
$ awk
'$0 ~ /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]:[0-5][0-9]:[0-5][0-9]/
{
if ($1" "$2 >= "2014-04-07 23:00") p=1;
if ($1" "$2 >= "2014-04-08 02:00:01") p=0;
}
p { print $0 }' log
(Beachten Sie, dass auch das Feldtrennzeichen geändert wird – zum Übergang zwischen Leerzeichen und Nicht-Leerzeichen, die Standardeinstellung)