2017-05-16 4 views
0

Ich habe eine Protokolldatei, die Ausführungsstartzeiten und Endzeiten verschiedener Threads enthält. Ich habe die Hälfte der Arbeit erledigt, aber ich brauche Hilfe, um die andere Hälfte zu beenden. Ich schrieb dieses Befehl-Wie finde ich das erste und letzte Vorkommen eines Feldes aus einer Protokolldatei?

cat 2017-05-15.log | grep 'Executing ETL' | tr -s ' ' | cut -f2,3,4,5,8 -d' ' | sort -k5 -n 

, die die folgende Ausgabe erzeugt:

15 May 2017 03:43:40 696 
15 May 2017 03:44:35 696 
15 May 2017 03:45:02 696 
15 May 2017 23:30:22 9502 
15 May 2017 23:49:40 9502 
15 May 2017 23:50:50 9502 
15 May 2017 23:51:11 9502 
15 May 2017 23:52:11 9502 
15 May 2017 23:52:42 9502 
15 May 2017 02:18:32 12795  
15 May 2017 02:19:35 12795 
15 May 2017 02:20:02 12795 
15 May 2017 02:33:39 13674 
15 May 2017 02:35:13 13674 
15 May 2017 02:35:42 13674 
15 May 2017 18:52:28 19143 
15 May 2017 18:53:01 19143 
15 May 2017 18:53:35 19143 
15 May 2017 18:53:59 19143 
15 May 2017 18:54:40 19143 

Dieser Ausgang auf die Prozess-ID sortiert, die die letzte Spalte ist. Das erste Vorkommen jeder Prozess-ID ist die Startzeit dieses Prozesses, während das letzte Vorkommen die Endzeit derselben ist. Ich muss nur die erste (Startzeit) und die letzte (Endzeit) jedes Prozesses anzeigen. Wie folgt aus:

15 May 2017 03:43:40 696 
15 May 2017 03:45:02 696 
15 May 2017 23:30:22 9502 
15 May 2017 23:52:42 9502 
15 May 2017 02:18:32 12795 
15 May 2017 02:20:02 12795 
15 May 2017 02:33:39 13674 
15 May 2017 02:35:42 13674 
15 May 2017 18:52:28 19143 
15 May 2017 18:54:40 19143 

Die Anzahl der Einträge für jeden Prozess-ID wird nicht fixiert. Die Ausgabe muss nicht unbedingt in diesem Format vorliegen. Aber ich muss in der Lage sein, die Start- und Endzeiten jedes Prozesses deutlich zu sehen.

+0

Wie ich in der Beschreibung gesagt, wird der Ausgang I in dem ersten Schritt erzeugt auf Prozess-ID (die 5. Spalte) sortiert. – RodrikTheReader

+0

Was ist, wenn es nur einen Eintrag gibt? –

Antwort

2

Wenn die PIDs nie verwechselt werden, dann ist das ziemlich einfach. Wir behalten nur die letzte Zeile und die PID bei und drucken die letzte und die aktuelle, wenn eine Änderung zu sehen ist. (Überspringen Druck wenn last leer ist, sonst bekommen wir eine leere Zeile mit zu beginnen, und erinnere mich an die letzte Zeile am END zu drucken.)

$ awk '($5 != lastpid) { if (last) print last; print $0; } 
     { lastpid = $5; last = $0 } 
     END {print last }' < times 
15 May 2017 03:43:40 696 
15 May 2017 03:45:02 696 
15 May 2017 23:30:22 9502 
15 May 2017 23:52:42 9502 
15 May 2017 02:18:32 12795  
15 May 2017 02:20:02 12795 
15 May 2017 02:33:39 13674 
15 May 2017 02:35:42 13674 
15 May 2017 18:52:28 19143 
15 May 2017 18:54:40 19143 
+0

Sie gehen hier davon aus, dass die Datei ** 2017-05-15.log ** das in der Frage angegebene Datenformat enthält, was nicht korrekt ist. Diese Datei enthält tatsächlich viele falsche Daten, die ich entfernt habe von "cat 2017-05-15.log | grep 'ETL ausführen" | tr -s' '| cut -f2,3,4,5,8 -d' '| sort -k5 -n ". Dieses kleine Problem beiseite, funktioniert Ihre Antwort, wenn ich die Ausgabe meines Befehls in eine Datei umleiten und diese Datei in Ihrem Befehl verwenden. Danke vielmals! :) – RodrikTheReader

+0

@RodrikTheReader, ja du hast Recht, ich bin heute ein bisschen langsam. Wir könnten wahrscheinlich durch die ganze Tortur awk, ohne Grep und Schnitt dazwischen, aber ohne das ursprüngliche Dateiformat zu sehen, das ist ein bisschen schwer zu tun. (Wenn die Eingabe sortiert ist, wird der awk-Teil einfacher, ohne dass das awk-Skript sortiert werden müsste, würde er alle PIDs gleichzeitig verfolgen.) Sie könnten auch die temporäre Datei überspringen und einfach das 'awk' in die Pipeline nach dem "Sortieren". – ilkkachu

0

Eine weitere in awk. Hash alle Premieren und dauert und Drucken am Ende. Wenn es nur ein Eintrag vorhanden ist, wird nur ein outputed werden:

$ awk ' 
{ 
    if($5 in f)        # if first exists 
     l[$5]=$0        # update last 
    else f[$5]=$0 }       # else first 
END { 
    for(i in f)        # loop all firsts 
     print f[i] ((i in l)?ORS l[i]:"") } # output firsts and lasts if exist 
' file 
15 May 2017 03:43:40 696 
15 May 2017 03:45:02 696 
15 May 2017 23:30:22 9502 
15 May 2017 23:52:42 9502 
15 May 2017 02:18:32 12795  
15 May 2017 02:20:02 12795 
15 May 2017 02:33:39 13674 
15 May 2017 02:35:42 13674 
15 May 2017 18:52:28 19143 
15 May 2017 18:54:40 19143 
Verwandte Themen