Filter Tail-Befehl durch mehrere Grep-Befehle, um Dateien zu trennen


5

Ich versuche, die Ausgabe einer Protokolldatei auf der Grundlage eines Grep-Filters in getrennte Protokolldateien zu filtern.

tail -f test.log | tee> (grep "Error"> error.log)> (grep "Warning" "> warning.log)

Auf diese Weise befinden sich alle "Fehler" -Einträge in einer Datei und alle "Warnung" -Einträge in einer separaten Datei.

Ich weiß, dass dies im Konzept funktioniert, da ich, wenn ich cat anstelle von tail verwende , die richtige Dateiausgabe erhalte, aber Änderungen nicht in Echtzeit nachverfolgen kann (was ich brauche, weil ich Ausgabeprotokolle von aktiv ausgeführten Tests beobachte).

Auch wenn ich die '>' Dateireferenten aus den grep- Befehlen entferne, werden die einzelnen grep-Ausgaben korrekt an die Konsole ausgegeben. Ich möchte jedoch auch eine aufgezeichnete Datei.

Antworten:

Beim Schreiben in eine Datei wurde die Ausgabe von grep gepuffert. Die Verwendung von egrep mit der Option --line-buffer hat das Verhalten behoben.

Der neue Befehl sieht folgendermaßen aus:

tail -f test.log | tee> (egrep - zeilengepuffertes "ERROR"> error.log)> (egrep - zeilengepuffertes "WARNING"> warning.log)


1
Könnte ein LineBuffer-Problem in tailf sein. Bitte überprüfen Sie : superuser.com/questions/59497/...
cfreire

Antworten:


0

Es ist möglicherweise einfacher, wenn Sie dazu mehr als eine Zeile verwenden. Sie könnten ein Bash-Skript schreiben:

#!/bin/bash

tail -f test.log | while read line; do
    if echo "$line" | grep -q "Error"; then
        echo "$line" >> error.log
    elif echo "$line" | grep -q "Warning"; then
        echo "$line" >> warning.log
    # The following is in case you want to print out lines that do not match 
    else
        echo "$line"
    fi
done

Mein nächster Schritt war, ein Python-Programm zu erstellen, mit dem ich tun kann, was ich will, da ich auf diese Weise viel flexibler werde. Ich wollte verstehen, warum ein Befehl, der so aussah, als ob er funktionieren sollte , nicht funktioniert. Es stellte sich heraus, dass es gepuffert wurde.
Ryan

0

@ Ryan, vielen Dank für die Beantwortung Ihrer Frage.
Eine andere (universelle) Möglichkeit, die Pufferung pro Zeile festzulegen, ist die Verwendung des stdbufBefehls:

tail -f test.log | tee >(stdbuf -oL grep "ERROR" > error.log) >(stdbuf -oL grep "WARNING" > warning.log)

Hier ist ein Auszug aus man stdbuf:

SYNOPSIS
   stdbuf OPTION... COMMAND
...
   -o, --output=MODE
          adjust standard output stream buffering
...
   If MODE is 'L' the corresponding stream will be line buffered.
....
EXAMPLES
   tail -f access.log | stdbuf -oL cut -d ' ' -f1 | uniq
   This will immedidately display unique entries from access.log
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.