¿Cómo ‘grep’ un flujo continuo?

¿Es posible usar grep en un flujo continuo?

Lo que quiero decir es una especie de comando tail -f , pero con grep en la salida para mantener solo las líneas que me interesan.

He intentado tail -f | grep pattern tail -f | grep pattern pero parece que grep solo se puede ejecutar una vez que termina la tail , es decir, nunca.

Active el modo de almacenamiento en línea de grep cuando use BSD grep (FreeBSD, Mac OS X, etc.)

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

No es necesario hacer esto para GNU grep (usado en casi cualquier Linux) ya que se vaciará por defecto (YMMV para otros gustos de Unix como SmartOS, AIX o QNX).

Uso el tail -f | grep tail -f | grep todo el tiempo.

Esperará hasta que grep se vacíe, no hasta que termine (estoy usando Ubuntu).

Creo que tu problema es que grep usa algunos buffer de salida. Tratar

 tail -f file | stdbuf -o0 grep my_pattern 

establecerá el modo de almacenamiento en búfer de salida de grep en no búfer.

En la mayoría de los casos, puede tail -f /var/log/some.log |grep foo y funcionará perfectamente.

Si necesita utilizar múltiples greps en un archivo de registro en ejecución y descubre que no obtiene ningún resultado, es posible que deba --line-buffered el --line-buffered en su grep (s) medio, así:

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

Si quiere encontrar coincidencias en todo el archivo (no solo en la cola), y quiere que se siente y espere nuevas coincidencias, esto funciona muy bien:

 tail -c +0 -f  | grep --line-buffered  

La bandera -c +0 dice que la salida debe comenzar 0 bytes ( -c ) desde el principio ( + ) del archivo.

puedes considerar esta respuesta como una mejora … generalmente estoy usando

 tail -F  | grep --line-buffered  -A 3 -B 5 

-F es mejor en caso de rotación de archivos (-f no funcionará correctamente si el archivo gira)

-A y -B es útil para obtener líneas justo antes y después de la ocurrencia del patrón … estos bloques aparecerán entre los separadores de líneas punteadas

No vi a nadie ofrecer mi habitual para esto:

 less +F  ctrl + c /  shift + f 

Prefiero esto, porque puedes usar ctrl + c para parar y navegar por el archivo cada vez, y luego presionar shift + f para regresar a la búsqueda en tiempo real.

Sí, esto realmente funcionará bien. Grep y la mayoría de los comandos de Unix operan en las transmisiones una línea a la vez. Cada línea que sale de la cola será analizada y transmitida si coincide.

sed sería el comando correcto (editor de flujo )

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

y luego si quería que el comando de cola salga una vez que encontró una cadena en particular:

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

Obviamente un bashism: $ BASHPID será la identificación del proceso del comando tail. El comando sed es el siguiente después de la cola en la tubería, por lo que la identificación del proceso sed será $ BASHPID + 1.

Use awk (otra gran utilidad de bash) en lugar de grep donde no tiene la opción de línea de búfer! Transmitirá continuamente tus datos desde la cola.

así es como usas grep

 tail -f  | grep pattern 

Así es como usarías awk

 tail -f  | awk '/pattern/{print $0}'