Den Input für den heutigen Artikel hat mir mein Arbeitskollege Jens geliefert. Wir hatten eine einfache Zeile in der Bash und standen beide recht ahnungslos davor, bis sich die Lösung durch ein wenig Recherche im Netz dann doch noch offenbart hat.
Es geht dabei um die Kombination der Tools tail
, grep
und cut
in der Kommandozeile.
Wenn man sich füllende Dateien weiterverarbeiten will (zum Beispiel log-Dateien), so liest man diese ganz gerne mit tail -f
ein und übergibt den aktuellen Input per Pipe an ein weiteres Tool.
Da man vor allem in log-Dateien bei Analysen durch bestimmte Zeilen benötigt, wird grep
genutzt. Grep filtert einen Input (normalerweise Dateien) nach einem gewissen Muster und in der Standard-Einstellung werden alle Zeilen die dem Muster entsprechen ausgegeben.
Zum Schluss benutzt man nun noch cut
, um eine Zeile zurecht zu schneiden. Dies ist zum Beispiel sehr praktisch wenn man einige Blöcke in einer Zeile hat, die durch Leerzeichen getrennt sind. Dann kann man recht leicht alle Blöcke ausgeben lassen die ab einer gewissen Blocknummer stehen. Somit kann man überflüssige Informationen bei einer Analyse entfernen.
Wenn man die 3 Tools zusammen nimmt ergibt das normalerweise folgende Zeile:
tail -f mylog.log | grep "ERROR" | cut -d " " -f 7-
Das bedeutet nun dass die mylog.log Datei eingelesen werden soll, so wie sie sich füllt, jede eingehende Zeile wird nach dem Schlüsselwort ERROR gefiltert und dann werden nur die Blöcke mit der Nummerierung größer 7 ausgegeben, wobei ein Block von einem anderen durch ein Leerzeichen getrennt ist.
Hört sich alles super an, funktioniert nur leider nicht!
Das Problem ist die Kombination aus tail -f
und cut
. Man kann die Tools jetzt aber durch einen weiteren Parameter von grep doch noch zur Mitarbeit überzeugen und dieser nennt sich line-buffered
. Der folgende Befehl liefert dann das erwartete Ergebnis:
tail -f mylog.log | grep --line-buffered "ERROR" | cut -d " " -f 7-