Czy można tego używać grep
w ciągłym strumieniu?
Mam na myśli rodzaj tail -f <file>
polecenia, ale z grep
wyjściem, aby zachować tylko te linie, które mnie interesują.
Próbowałem, tail -f <file> | grep pattern
ale wydaje się, że grep
można go wykonać tylko po tail
zakończeniu, czyli nigdy.
tail -f file
działa (widzę nową produkcję w czasie rzeczywistym)Odpowiedzi:
Włącz
grep
tryb buforowania linii podczas korzystania z BSD grep (FreeBSD, Mac OS X itp.)Nie musisz tego robić w przypadku GNU grep (używanego prawie na każdym Linuksie), ponieważ domyślnie będzie się opróżniał (YMMV dla innych systemów uniksowych, takich jak SmartOS, AIX lub QNX).
źródło
strace
. Bez tego--line-buffered
nie będzie działać.tail -f | grep
i--line-buffered
rozwiązałem go dla mnie (w Ubuntu 14.04, GNU grep wersja 2.16). Gdzie jest zaimplementowana logika „użyj buforowania linii, jeśli standardowe wyjście jest tty”? W git.savannah.gnu.org/cgit/grep.git/tree/src/grep.c ,line_buffered
jest ustawiony tylko przez parser argumentów.--line-buffered
nie otrzymuję danych wyjściowych. Jednak po przetestowaniu wygląda na to, że GNU grep robi to, co opisujesz. Tak jak większość rzeczy w Uniksie, zależy to od implementacji twojej platformy. Ponieważ pytanie nie określało platformy, twoje informacje wydają się fałszywe - po przejrzeniu kodu BSD grep i porównaniu go z GNU grep, zachowanie jest zdecydowanie kontrolowane przez opcję --line-buforowaną. Tyle, że tylko GNU grep domyślnie się opróżnia.Używam
tail -f <file> | grep <pattern>
cały czas.Poczeka, aż grep się opróżni, a nie do końca (używam Ubuntu).
źródło
Myślę, że twoim problemem jest to, że grep używa buforowania danych wyjściowych. Próbować
ustawia tryb buforowania wyjścia grep na niebuforowany.
źródło
grep
.unbuffer
(wexpect-dev
pakiecie na debianie) jest królem . Więc użyłbym unbuffer zamiast stdbuf.top
z stdbuf i unbuffer). I tak naprawdę nie ma „magicznego” rozwiązania: czasami buforowanie również zawiedzie, na przykład awk używa innej implementacji bufora (stdbuf też zawiedzie).stdbuf
, `unbuffer i buforowanie stdio na pixelbeat.org/programming/stdio_bufferingJeśli chcesz znaleźć dopasowania w całym pliku (nie tylko ogon) i chcesz, aby siedział i czekał na nowe dopasowania, działa to dobrze:
-c +0
Flaga mówi, że wyjście powinno rozpocząć0
bajtów (-c
) od początku (+
) z pliku.źródło
W większości przypadków możesz
tail -f /var/log/some.log |grep foo
i będzie działać dobrze.Jeśli potrzebujesz użyć wielu grepów w działającym pliku dziennika i okaże się, że nie otrzymujesz danych wyjściowych, może być konieczne włożenie
--line-buffered
przełącznika do środkowego grepa (s), tak jak poniżej:źródło
możesz uznać tę odpowiedź za udoskonalenie .. zwykle używam
-F jest lepszy w przypadku obracania pliku (-f nie będzie działał poprawnie, jeśli plik został obrócony)
-A i -B są przydatne do pobierania linii tuż przed i po wystąpieniu wzoru. Bloki te pojawią się między separatorami linii przerywanej
Ale dla mnie wolę robić następujące rzeczy
jest to bardzo przydatne, jeśli chcesz przeszukiwać dzienniki przesyłane strumieniowo. Mam na myśli cofanie się i naprzód i głębokie spojrzenie
źródło
grep -C 3 <pattern>
, zastępuje -A <N> i -B <N>, jeśli N jest takie samo.Nie widziałem nikogo, kto zaoferowałby mi to za to:
Wolę to, ponieważ możesz użyć
ctrl + c
do zatrzymania pliku i poruszania się po nim, a następnie po prostu naciśnij,shift + f
aby powrócić do wyszukiwania strumieniowego na żywo.źródło
sed byłby lepszym wyborem ( edytor strumieniowy )
tail -n0 -f <file> | sed -n '/search string/p'
a jeśli chcesz, aby polecenie tail zakończyło działanie po znalezieniu określonego ciągu:
tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'
Oczywiście bashism: $ BASHPID będzie identyfikatorem procesu polecenia tail. Komenda sed jest następna po ogonie w rurze, więc identyfikator procesu sed to $ BASHPID + 1.
źródło
$BASHPID+1
) będzie twój, jest fałszywe w wielu sytuacjach i nie rozwiązuje to problemu buforowania, o który prawdopodobnie chciał zapytać OP. W szczególności zalecased
sięgrep
tutaj wydaje się jedynie kwestią (wątpliwej) preferencji. (Możesz uzyskaćp;q
zachowanie,grep -m 1
jeśli to jest punkt, który próbujesz osiągnąć.)--line-buffered
nie. Szczerze nie rozumiem minus 1.Tak, to naprawdę będzie działać dobrze.
Grep
i większość poleceń Uniksa działa na strumieniach jedna linia na raz. Każda linia wychodząca z ogona zostanie przeanalizowana i przekazana, jeśli pasuje.źródło
grep
jest to ostatnie polecenie w łańcuchu potoków, będzie działać zgodnie z objaśnieniem. Jednak jeśli jest w środku, buforuje około 8k danych naraz.To jedno polecenie działa dla mnie (Suse):
zbieranie danych logowania do usługi pocztowej
źródło
z pewnością nie odniesiesz sukcesu
kiedy używasz „colortail” jako aliasu dla ogona, np. w bash
możesz sprawdzić według typu aliasu, czy wyświetla to coś w rodzaju aliasu ogona
colortail -n 30
. to masz winowajcę :)Rozwiązanie:
usuń alias za pomocą
upewnij się, że używasz „prawdziwego” pliku binarnego ogona za pomocą tego polecenia
co powinno wypisać coś takiego:
a następnie możesz uruchomić polecenie
Powodzenia.
źródło
Użyj awk (kolejne świetne narzędzie do bash) zamiast grep, gdzie nie masz opcji buforowanej linii! Będzie stale przesyłać dane z ogona.
tak używasz grep
Tak użyłbyś awk
źródło
{print $0}
jest zbędny, ponieważ drukowanie jest domyślną czynnością, gdy warunek mija.)