Come applicare un filtro all'output in tempo reale di `tail -f`?


60
tail -f path

Quanto sopra produrrà immediatamente modifiche al file, ma voglio applicare un filtro all'output, mostrare solo quando è presente una parola chiave xxx.

Come affrontare questo?


1
Contrassegnare le risposte come accettate aiuta gli altri che leggono le tue domande e le loro risposte a sapere quale risposta potrebbe avere maggiori probabilità di aiutarle se hanno una domanda o un problema simili. Puoi rivisitare le tue domande precedenti facendo clic sul tuo nome utente.
Dennis Williamson,

Risposte:


84

Con Unix puoi convogliare l'output di un programma in un altro.

Quindi, per filtrare la coda, puoi usare grep:

tail -f path | grep your-search-filter

Ma supponiamo che tu abbia 100 righe nella coda (fine del file) e queste righe sono quelle che vuoi filtrare. La tua soluzione
TraderJoeChicago,

1
Se vuoi solo cercare le ultime 100 righe di un file prova tail -100 path | grep xxx
Adders UK

15

Risposta breve: tail -f somefile | grep somepattern

Tuttavia, questo tende a non essere all'altezza. Supponiamo che tu stia eseguendo la coda di un file che viene ruotato spesso (se si tratta di un registro di debug, potrebbe essere ruotato più volte). In quel caso tail -Fè tuo amico. Ti lascio cercare la differenza.

Ma tail -fe tail -Fstampare una serie di prime linee, che spesso è indesiderabile in questo caso d'uso, quindi in questo caso add-n0

tail -F -n0 somefile | grep somepattern

Andrà bene, fino a quando non si desidera fare qualche altro filtro e quindi è necessario fare attenzione al buffering. stdout è bufferizzato di linea per impostazione predefinita quando si scrive su un terminale ma quando è completamente bufferizzato quando si scrive su una pipe. Quindi quanto segue emetterà delle linee non appena vengono trovate, perché tailè esplicitamente bufferizzato (o scarica il suo output alla fine di ogni riga), ed grepè anche bufferizzato perché il suo output sta andando al tuo terminale:

tail -F -n0 somefile | grep somepattern

Ma poi decidi di utilizzare qualcosa di simile awko cutdi elaborare ulteriormente l'output.

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

E ora ti chiedi dove sia andato il tuo output ... a seconda del volume dei log, potresti scoprire che ottieni l'output, ma sarà una pagina alla volta perché ora lo stdout grepsta funzionando in modo completamente bufferizzato, e quindi awkriceve input 4kB alla volta (per impostazione predefinita).

In questo caso, puoi dire grepdi rendere sempre bufferizzata la linea stdout usando l' --line-bufferedopzione.

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

Tuttavia, la maggior parte dei comandi non ha un analogo di --line-buffered. Nel caso di strumenti più scriptabili, è possibile utilizzare una funzione per svuotare l'output (ad es. In awk, la funzione è fflush(), che condivide lo stesso nome della sua controparte C, strumenti come Perl e Python hanno qualcosa di simile).

Con artisti del calibro cutprobabilmente sei sfortunato; ... ma potresti provare a cercarlo unbuffer, penso sia qualcosa fornito dalla expecttoolchain (non l'ho mai usato).

Spero che l'abbia trovato utile.

Saluti, Cameron


Apprezzo molto la spiegazione del perché questo funziona in modalità buffer di linea. È una visione eccellente, grazie.
Verde,

2

e puoi usare più pipe e greps, ed escludere cose con grep -v, ottenere insensibilità ai casi con grep -i, ecc.

cioè: tail -100f / var / log / messages | grep -V ACPI | grep -i ata

inizia a seguire la coda di 100 linee dalla fine e continua a seguire la coda, prima escludi tutte le linee con ACPI, quindi mostra le linee con ata, ATA o qualsiasi combinazione di quelle.

Un altro utile è le opzioni ABC, per le righe After, Before e Context (righe prima e dopo).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.