risposta-alla-domanda-sullo-sviluppo-web-bd.com

Vieni 'grep' un flusso continuo?

È possibile utilizzare grep su un flusso continuo?

Quello che intendo è una specie di comando tail -f <file>, ma con grep sull'output per mantenere solo le righe che mi interessano.

Ho provato tail -f <file> | grep pattern ma sembra che grep possa essere eseguito solo quando tail finisce, cioè mai.

638
Matthieu Napoli

Attiva la modalità di bufferizzazione della riga grep quando utilizzi BSD grep (FreeBSD, Mac OS X ecc.)

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

Non è necessario eseguire questa operazione per GNU grep (utilizzato praticamente su qualsiasi Linux) poiché verrà svuotato di default (YMMV per altri like di Unix come SmartOS, AIX o QNX).

1190
tad

Io uso il tail -f <file> | grep <pattern> tutto il tempo.

Aspetterà fino a quando grep arriverà, non prima che finisca (sto usando Ubuntu).

113
Irit Katriel

Penso che il tuo problema sia che grep usa un buffer di output. Provare

tail -f file | stdbuf -o0 grep my_pattern

imposterà la modalità buffer di uscita di grep su unbuffered.

56
XzKto

Nella maggior parte dei casi, puoi tail -f /var/log/some.log |grep foo e funzionerà perfettamente.

Se è necessario utilizzare più greps su un file di registro in esecuzione e si scopre che non si ottiene alcun output, potrebbe essere necessario inserire lo switch --line-buffered in middle grep (s), in questo modo:

tail -f /var/log/some.log | grep --line-buffered foo | grep bar
10
Dale Anderson

Se vuoi trovare le corrispondenze nel intero file (non solo nella coda), e vuoi che si sieda e aspetti nuove corrispondenze, questo funziona bene:

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

Il flag -c +0 dice che l'output dovrebbe iniziare 0 byte (-c) dall'inizio (+) del file.

9
Ken Williams

Non ho visto nessuno offrire il mio solito go-to per questo:

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

Preferisco questo, perché puoi usare ctrl + c per fermarti e navigare nel file ogni volta, e poi premere shift + f per tornare alla ricerca live streaming.

5
Hans.Loven.work

sed sarebbe una scelta migliore ( stream editor)

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

e quindi se si desidera che il comando tail esca dopo aver trovato una stringa particolare:

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

Ovviamente un bashismo: $ BASHPID sarà l'id di processo del comando tail. Il comando sed è il prossimo dopo tail nella pipe, quindi l'id del processo sed sarà $ BASHPID + 1.

3
Christian Herr

potresti considerare questa risposta come un miglioramento .. di solito sto usando

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

-F è migliore in caso di rotazione del file (-f non funziona correttamente se il file è ruotato)

-A e -B è utile per ottenere linee appena prima e dopo l'occorrenza del modello .. questi blocchi appariranno tra i separatori di linee tratteggiate

2
mebada

Questo comando funziona per me (Suse):

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

raccolta degli accessi al servizio di posta

1
user10584393

Sì, funzionerà davvero bene. Grep e la maggior parte dei comandi Unix operano su flussi una riga alla volta. Ogni linea che esce dalla coda verrà analizzata e trasmessa se corrisponde.

0
Caleb