Jak "grep" ciągły strumień?

Czy Można używać grep w ciągłym strumieniu?

Mam na myśli coś w rodzaju tail -f <file> polecenia, ale z grep na wyjściu, aby zachować tylko te linie, które mnie interesują.

Próbowałem tail -f <file> | grep pattern ale wygląda na to, że grep można wykonać tylko raz tail, czyli nigdy.

Author: Marcin, 2011-08-23

12 answers

Włączanie trybu buforowania linii grep Podczas korzystania z BSD grep (FreeBSD, Mac OS X itp.)

tail -f file | grep --line-buffered my_pattern

Wygląda na to, że jakiś czas temu --line-buffered nie miało to znaczenia dla GNU grep (używanego w prawie każdym Linuksie), ponieważ było domyślnie spłukiwane (YMMV dla innych Uniksów, takich jak SmartOS, AIX czy QNX). Jednak od listopada 2020 r. --line-buffered jest potrzebny (przynajmniej w przypadku GNU grep 3.5 W openSUSE, ale wydaje się ogólnie potrzebny na podstawie komentarzy poniżej).

 1408
Author: tad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-30 13:23:37

Używam tail -f <file> | grep <pattern> cały czas.

Będzie czekać aż grep spłukuje, a nie do końca (używam Ubuntu).

 118
Author: Irit Katriel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-29 06:56:36

Myślę, że Twoim problemem jest to, że grep używa buforowania wyjścia. Try

tail -f file | stdbuf -o0 grep my_pattern

Ustawia tryb buforowania wyjścia grepa na niebuforowany.

 72
Author: XzKto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-23 14:03:27

Jeśli chcesz znaleźć dopasowania w całym pliku (nie tylko ogonie), i chcesz, aby siedział i czekał na nowe dopasowania, działa to ładnie:

tail -c +0 -f <file> | grep --line-buffered <pattern>

Znacznik -c +0 mówi, że wyjście powinno zaczynać się 0 bajtów (-c) Od początku (+) pliku.

 14
Author: Ken Williams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-11 22:34:45

W większości przypadków, można {[1] } i będzie działać dobrze.

Jeśli potrzebujesz użyć wielu grepów na uruchomionym pliku dziennika i okaże się, że nie masz wyjścia, być może będziesz musiał umieścić przełącznik --line-buffered w swoim środkowym grep(y), w następujący sposób:

tail -f /var/log/some.log | grep --line-buffered foo | grep bar
 13
Author: Dale Anderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-04 17:14:50

Możesz uznać tę odpowiedź za ulepszenie .. zazwyczaj używam

tail -F <fileName> | grep --line-buffered  <pattern> -A 3 -B 5

-F jest lepsze w przypadku rotacji pliku (- F nie będzie działać poprawnie, jeśli plik zostanie obrócony)

- a i-B są przydatne do uzyskania linii tuż przed i po wystąpieniu wzorca .. bloki te pojawią się między przerywanymi separatorami linii

Ale dla mnie wolę robić następujące

tail -F <file> | less

Jest to bardzo przydatne, jeśli chcesz przeszukać strumieniowane dzienniki. To znaczy, idź do przodu i do tyłu i spójrz deeply

 8
Author: mebada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-10 07:13:46

Nie widziałem, żeby ktoś oferował mi to co zwykle:

less +F <file>
ctrl + c
/<search term>
<enter>
shift + f

Wolę to, ponieważ możesz użyć ctrl + c, aby zatrzymać i przejść przez plik kiedykolwiek, a następnie po prostu naciśnij shift + f, aby powrócić do wyszukiwania na żywo, strumieniowego.

 6
Author: Hans.Loven.work,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-10 02:20:15

Sed byłby lepszym wyborem (stream editor)

tail -n0 -f <file> | sed -n '/search string/p'

A następnie, jeśli chcesz, aby Komenda tail zakończyła się po znalezieniu określonego ciągu znaków:

tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'

Oczywiście bashism: $BASHPID będzie ID procesu komendy tail. Polecenie sed jest następne po ogonie w rurze, więc id procesu sed będzie wynosić $BASHPID+1.

 4
Author: Christian Herr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-11 19:35:58

Tak, to będzie działać dobrze. Grep i większość komend uniksowych operuje na strumieniach po jednej linii naraz. Każda linia, która wyjdzie z ogona, zostanie przeanalizowana i przekazana, jeśli pasuje.

 2
Author: Caleb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-23 13:41:32

To polecenie działa dla mnie (Suse):

mail-srv:/var/log # tail -f /var/log/mail.info |grep --line-buffered LOGIN  >> logins_to_mail

Zbieranie loginów do serwisu pocztowego

 1
Author: user10584393,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-31 07:02:47

Z pewnością ci się nie uda

tail -f /var/log/foo.log |grep --line-buffered string2search

Kiedy używasz" colortail " jako aliasu dla ogona, np. in bash

alias tail='colortail -n 30'

Możesz sprawdzić przez wpisz alias jeśli to wyjdzie coś w rodzaju tail isan alias of colortail -n 30. to masz swojego winowajcę:)

Rozwiązanie:

Usuń alias za pomocą

unalias tail

Upewnij się, że używasz 'prawdziwego' kodu binarnego za pomocą tego polecenia

type tail

Który powinien wypisać coś w stylu:

tail is /usr/bin/tail

I wtedy możesz uruchomić swój polecenie

tail -f foo.log |grep --line-buffered something
Powodzenia.
 -2
Author: user882786,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-17 10:40:48

Użyj awk (innego wielkiego narzędzia bash) zamiast grepa, gdzie nie masz opcji buforowanej linii! Będzie stale przesyłać strumieniowo dane z tail.

Tak się używa grepa

tail -f <file> | grep pattern

Tak można używać awk

tail -f <file> | awk '/pattern/{print $0}'
 -4
Author: Atif,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-22 13:39:20