Filtruj polecenie tail przez wiele poleceń grep, aby oddzielić pliki

5

Próbuję filtrować dane wyjściowe jednego pliku dziennika na oddzielne pliki dziennika oparte na filtrze grep.

tail -f test.log | tee & gt; (grep „Błąd” & gt; error.log) & gt; (grep „Ostrzeżenie” ”& gt;   warning.log)

W ten sposób wszystkie wpisy „Błąd” znajdują się w jednym pliku, a wszystkie wpisy „Ostrzeżenie” znajdują się w osobnym pliku.

Wiem, że to działa w koncepcji, ponieważ jeśli używam kot zamiast ogon , Otrzymuję poprawne wyjście pliku, ale nie mogę śledzić zmian w czasie rzeczywistym (czego potrzebuję, ponieważ oglądam dzienniki wyjściowe z aktywnych testów)

Ponadto, jeśli usunę „& gt;” plik re-directors z grep polecenia wyprowadza poszczególne wyjścia grep do konsoli poprawnie; jednak chcę także nagrać plik.

Odpowiedź:

Podczas zapisywania do pliku wyjście grep był buforowany. Za pomocą egrep z --line-buffer opcja naprawiła zachowanie.

Nowe polecenie wygląda tak:

tail -f test.log | tee & gt; (egrep - line-buffered "ERROR" & gt; error.log) & gt;

Ryan
źródło
1
Może to być problem lineBuffera w tailf. Proszę sprawdzić: superuser.com/questions/59497/…
cfreire
To naprawiło mój problem, dziękuję!
Ryan

Odpowiedzi:

0

Może być łatwiej, jeśli użyjesz do tego więcej niż jednej linii. Możesz napisać skrypt basha:

#!/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
hololeap
źródło
Moim następnym krokiem było stworzenie programu Pythona do robienia tego, co chcę, ponieważ w ten sposób zyskałbym znacznie większą elastyczność. Chciałem zrozumieć, dlaczego polecenie, które wyglądało tak powinien praca nie była. Okazuje się, że był buforowany.
Ryan
0

@Ryan, dzięki za wysłanie odpowiedzi na twoje pytanie.
innym (uniwersalnym) sposobem ustawiania buforowania na linii jest użycie stdbuf dowództwo:

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

oto fragment z 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
atti
źródło