¿Es posible usarlo grep
en una secuencia continua?
Lo que quiero decir es una especie de tail -f <file>
comando, pero con grep
la salida para mantener solo las líneas que me interesan.
Lo he intentado tail -f <file> | grep pattern
pero parece que grep
solo se puede ejecutar una vez que tail
finaliza, es decir, nunca.
tail -f file
funciona (veo la nueva salida en tiempo real)Respuestas:
Active el
grep
modo de almacenamiento en línea de la memoria intermedia cuando utilice BSD grep (FreeBSD, Mac OS X, etc.)No necesita hacer esto para GNU grep (usado en prácticamente cualquier Linux) ya que se vaciará por defecto (YMMV para otros gustos de Unix como SmartOS, AIX o QNX).
fuente
strace
. Sin el--line-buffered
, no funcionará.tail -f | grep
y lo--line-buffered
resuelve por mí (en Ubuntu 14.04, GNU grep versión 2.16). ¿Dónde está implementada la lógica "usar el almacenamiento en línea de la memoria intermedia si stdout es un tty"? En git.savannah.gnu.org/cgit/grep.git/tree/src/grep.c ,line_buffered
solo lo establece el analizador de argumentos.--line-buffered
obtener ningún resultado. Sin embargo, después de las pruebas, parece que GNU grep hace lo que usted describe. Entonces, como la mayoría de las cosas Unix, depende de la implementación de su plataforma. Dado que la pregunta no especificaba la plataforma, su información parece ser falsa: después de revisar el código para BSD grep y compararlo con GNU grep, el comportamiento está definitivamente controlado por la opción --line-buffer. Es solo que solo GNU grep se descarga por defecto.Lo uso
tail -f <file> | grep <pattern>
todo el tiempo.Esperará hasta que grep se ruborice, no hasta que termine (estoy usando Ubuntu).
fuente
Creo que su problema es que grep usa algo de almacenamiento en búfer de salida. Tratar
establecerá el modo de almacenamiento en búfer de salida de grep en sin búfer.
fuente
grep
.unbuffer
(en elexpect-dev
paquete de debian) es el rey . Entonces usaría unbuffer sobre stdbuf.top
con stdbuf y unbuffer). Y realmente no existe una solución 'mágica': el unbuffer falla a veces también, por ejemplo awk usa una implementación de buffer diferente (stdbuf también fallará).stdbuf
, `unbuffer, y stdio buffering en pixelbeat.org/programming/stdio_bufferingSi desea encontrar coincidencias en todo el archivo (no solo la cola), y desea que se asiente y espere nuevas coincidencias, esto funciona bien:
La
-c +0
bandera dice que la salida debe iniciar0
bytes (-c
) desde el principio (+
) del archivo.fuente
En la mayoría de los casos, puede
tail -f /var/log/some.log |grep foo
hacerlo y funcionará bien.Si necesita usar múltiples greps en un archivo de registro en ejecución y encuentra que no obtiene salida, es posible que deba pegar el
--line-buffered
interruptor en su grep medio (s), de esta manera:fuente
puede considerar esta respuesta como una mejora ... generalmente estoy usando
-F es mejor en caso de rotación del archivo (-f no funcionará correctamente si el archivo gira)
-A y -B es útil para obtener líneas justo antes y después de la aparición del patrón ... estos bloques aparecerán entre los separadores de líneas discontinuas
Pero para mí prefiero hacer lo siguiente
Esto es muy útil si desea buscar dentro de los registros transmitidos. Me refiero a retroceder y avanzar y mirar profundamente
fuente
grep -C 3 <pattern>
, reemplaza -A <N> y -B <N> si N es igual.No vi a nadie ofrecer mi habitual para esto:
Prefiero esto, porque puedes usarlo
ctrl + c
para detenerte y navegar por el archivo cuando lo desees , y luego simplemente presionarshift + f
para volver a la búsqueda de transmisión en vivo.fuente
sed sería una mejor opción ( editor de flujo )
tail -n0 -f <file> | sed -n '/search string/p'
y luego si desea que el comando de cola salga una vez que encuentre una cadena particular:
tail --pid=$(($BASHPID+1)) -n0 -f <file> | 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.
fuente
$BASHPID+1
) será suyo es falso en muchas situaciones, y esto no hace nada para resolver el problema de almacenamiento en búfer, que probablemente es lo que el OP estaba tratando de preguntar. En particular, la recomendaciónsed
másgrep
aquí parece simplemente una cuestión de preferencia (dudosa). (Usted puede obtenerp;q
un comportamiento congrep -m 1
si ese es el punto que está tratando de entregar.)--line-buffered
no lo hizo. Sinceramente, no entiendo el menos 1.Sí, esto realmente funcionará bien.
Grep
y la mayoría de los comandos de Unix operan en transmisiones una línea a la vez. Cada línea que sale de la cola se analizará y pasará si coincide.fuente
grep
es el último comando en la cadena de tuberías, actuará como usted explica. Sin embargo, si está en el medio, almacenará alrededor de 8k de salida a la vez.Este comando funciona para mí (Suse):
recolectando inicios de sesión al servicio de correo
fuente
ciertamente no tendrás éxito con
cuando usa "colortail" como un alias para la cola, por ejemplo. en bash
puede verificar por tipo alias si esto genera algo como tail isan alias of
colortail -n 30
. entonces tienes tu culpable :)Solución:
eliminar el alias con
asegúrese de que está utilizando el binario de cola 'real' con este comando
que debería generar algo como:
y luego puedes ejecutar tu comando
Buena suerte.
fuente
¡Usa awk (otra gran utilidad bash) en lugar de grep donde no tienes la opción de buffer de línea! Continuamente transmitirá sus datos desde la cola.
así es como usas grep
Así es como usarías awk
fuente
{print $0}
es redundante, ya que la impresión es la acción predeterminada cuando pasa una condición).