seguir un archivo de registro pero mostrar solo líneas específicas

29

Estoy siguiendo un archivo de registro con la bandera -f. Luego estoy canalizando esto a grep, para encontrar solo líneas que contengan "X". Eso funciona perfectamente bien. Ahora quiero canalizar esto nuevamente en otro grep, que eliminará todas las líneas que contienen "Y". Cuando agrego la segunda tubería, el archivo deja de actualizarse y parece que no llegan datos.

Este es el comando que funciona: tail -f my_file.log | grep "X"

Este es el comando que no: tail -f my_file.log | grep "X" | grep -v "Y"

¿Cómo debo estructurar esto para que el comando funcione?

Ori Horev
fuente
1
intente hacer una tubería por una tubería, cambie la secuencia, haga tail -f file|grep -v "Y". Si la salida está bien, proceda a agregar grep "X".
Aizuddin Zali

Respuestas:

38

Como la salida de grepse almacena en búfer, use la --line-bufferedopción de greppara habilitar el almacenamiento en línea de la memoria intermedia:

tail -f /path/to/log | grep --line-buffered 'X' | grep -v 'Y'

Si grepno tiene la opción, puede usar stdbufcomo alternativa:

tail -f /path/to/log | stdbuf -oL grep 'X' | grep -v 'Y'
heemayl
fuente
1
Me pregunto cómo stdbufdice libstdbuf.soqué configuración usar.
Kasperd
@kasperd: variables de entorno.
Nate Eldredge
1
@NateEldredge Ya busqué variables de entorno en la salida diff -u <(env) <(stdbuf env)y no encontré ninguna. Pero ahora me doy cuenta de que lo que debería haber probado fue diff -u <(env) <(stdbuf -oL env).
Kasperd
También soy el mismo tipo de problema. mi caso es que necesito imprimir todas las líneas que contienen 'aaa' y 'bbb'. Por encima de la primera solución no funciona. La segunda solución es trabajar para que 'aaa' exista y 'bbb' no exista. Ambos existen no funciona. sin dar salida. mi comando se ve así: tail -f test.txt | stdbuf -oL grep 'aaa' | grep 'bbb' no da ningún resultado. Me podría ayudar.
Dom
18

Normalmente encuentro más útil awkpara este tipo de comprobaciones lógicas:

tail -f /path/to/log | awk '/X/ && !/Y/'
#                           ^^^    ^^^^
#                   this I want    but not this

Probado por tener dos pestañas, una en la que sigo escribiendo seq 20 >> myfiley la otra por ejemplo tail -f myfile | awk '/3/ && !/13/'.

fedorqui
fuente
15

Otro enfoque sería utilizar una sola grepinvocación en lugar de dos y así evitar el problema del almacenamiento en búfer. Simplemente use expresiones regulares que coincidan con líneas que consisten en 0 o más caracteres que no sean Y, luego una X y luego 0 o más que no sean Y nuevamente hasta el final de la línea "

tail -f /path/to/log | grep '^[^Y]*X[^Y]*$'
terdon
fuente