Jak zastosować filtr do wyjścia `tail -f` w czasie rzeczywistym?

60
tail -f path

Powyższe spowoduje natychmiastowe zmodyfikowanie pliku, ale chcę zastosować filtr do pliku wyjściowego, pokaże się tylko, gdy znajdzie się xxxw nim słowo kluczowe .

Jak do tego podejść?

wampirzyca
źródło
1
Oznaczenie odpowiedzi jako zaakceptowanych pomaga innym, którzy czytają twoje pytania i ich odpowiedzi, dowiedzieć się, która odpowiedź może być bardziej pomocna, jeśli mają podobne pytanie lub problem. Możesz wrócić do wcześniejszych pytań, klikając swoją nazwę użytkownika.
Dennis Williamson,

Odpowiedzi:

84

Dzięki Uniksowi możesz przesyłać dane wyjściowe z jednego programu do drugiego.

Aby przefiltrować ogon, możesz użyć grep:

tail -f path | grep your-search-filter
AddersUK
źródło
Ale powiedzmy, że masz 100 linii na końcu (koniec pliku), a te linie są tymi, które chcesz filtrować. Twoje rozwiązanie
TraderJoeChicago,
1
Jeśli chcesz przeszukać tylko 100 ostatnich linii pliku, spróbuj tail -100 path | grep xxx
AddersUK
15

Krótka odpowiedź: tail -f somefile | grep somepattern

Jednak zwykle nie wystarcza. Załóżmy, że dostosowujesz plik, który jest często obracany (jeśli jest to dziennik debugowania, może być obracany wiele razy). W takim razie tail -Fjest twoim przyjacielem. Pozwolę ci sprawdzić różnicę.

Ale tail -fi tail -Fwydrukuj najpierw kilka linii, co często jest niepożądane w tym przypadku użycia, więc w tym przypadku dodaj-n0

tail -F -n0 somefile | grep somepattern

Będzie dobrze, dopóki nie będziesz chciał wykonać innego filtrowania, a potem musisz wystrzegać się buforowania. stdout jest domyślnie buforowany liniowo podczas zapisywania na terminalu, ale podczas pełnego buforowania podczas zapisywania na potoku. Tak więc następujące wyemitują linie, gdy tylko zostaną znalezione, ponieważ tailsą jawnie buforowane w linii (lub opróżniają swoje wyjście na końcu każdej linii), a greptakże są buforowane w linii, ponieważ ich dane wyjściowe trafiają do twojego terminala:

tail -F -n0 somefile | grep somepattern

Ale wtedy decydujesz się użyć czegoś podobnego awklub cutdo dalszego przetworzenia wyniku.

tail -F -n0 somefile | grep somepattern | awk '{print $3}'

A teraz zastanawiasz się, dokąd poszedł twój wynik ... w zależności od ilości dzienników, może się okazać, że dostajesz wyjście, ale będzie to strona na raz, ponieważ teraz standardowe wyjście grepdziała w pełni buforowany sposób, i tak awkodbiera wejściowo 4kB na raz (domyślnie).

W takim przypadku możesz grepustawić --line-bufferedopcję buforowania linii standardowej za pomocą opcji.

tail -F -n0 somefile | grep --line-buffered somepattern | ...

Jednak większość poleceń nie ma odpowiednika --line-buffered. W przypadku bardziej skryptowalnych narzędzi można użyć funkcji do wypłukania danych wyjściowych (np. W awk, funkcja jest fflush(), która ma taką samą nazwę jak jej odpowiednik C, narzędzia takie jak Perl i Python mają coś podobnego).

Z takimi jak cutty prawdopodobnie nie masz szczęścia; ... ale możesz spróbować wyszukać unbuffer, co wydaje mi się, że coś zapewnia expectłańcuch narzędzi (nigdy tego nie używałem).

Mam nadzieję, że uznasz to za przydatne.

Pozdrawiam, Cameron

Cameron Kerr
źródło
Naprawdę doceniam wyjaśnienie, dlaczego działa to w trybie buforowania linii. To doskonały wgląd, dziękuję.
Green
2

i możesz używać wielu potoków i grepów, a także wykluczać rzeczy za pomocą grep -v, uzyskać niewrażliwość na wielkość liter za pomocą grep -i itp.

tj .: tail -100f / var / log / messages | grep -V ACPI | grep -i ata

rozpocznij tailing 100 linii od końca i kontynuuj tailing, najpierw wyklucz wszystkie linie z ACPI, a następnie pokaż linie z ata, ATA lub dowolną ich kombinacją.

Kolejną przydatną są opcje ABC dla linii Po, Przed i Kontekst (linie przed i po).

Ronald Pottol
źródło