finalizar um arquivo de log, mas mostrar apenas linhas específicas


29

Estou seguindo um arquivo de log com o sinalizador -f. Então, eu estou colocando isso no grep, para encontrar apenas linhas que contenham "X". Isso está funcionando perfeitamente bem. Agora quero canalizar isso novamente para outro grep, que removerá todas as linhas que contêm "Y". Quando adiciono o segundo canal, o arquivo para de atualizar e parece que não há dados chegando.

Este é o comando que funciona: tail -f my_file.log | grep "X"

Este é o comando que não: tail -f my_file.log | grep "X" | grep -v "Y"

Como devo estruturar isso para que o comando funcione?


1
tente fazer um tubo por um tubo, mude a sequência, faça tail -f file|grep -v "Y". se a saída estiver correta, prossiga para acrescentar grep "X".
Aizuddin Zali

Respostas:


38

Como a saída de grepé armazenada em buffer, use a --line-bufferedopção de greppara ativar o buffer de linha:

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

Se o seu grepnão tiver a opção, você pode usar stdbufcomo alternativa:

tail -f /path/to/log | stdbuf -oL grep 'X' | grep -v 'Y'

1
Gostaria de saber como stdbufinforma libstdbuf.soquais configurações usar.
kasperd

@kasperd: Variáveis ​​de ambiente.
Node Eldredge

1
@NateEldredge Eu já procurei variáveis ​​de ambiente na saída diff -u <(env) <(stdbuf env)e não encontrei nenhuma. Mas agora percebo que o que eu deveria ter testado era diff -u <(env) <(stdbuf -oL env).
kasperd

Eu também sou o mesmo tipo de problema. no meu caso, preciso imprimir todas as linhas que contêm 'aaa' e 'bbb'. A primeira solução acima não está funcionando. A segunda solução está funcionando para 'aaa' existir e 'bbb' não existir. ambos existem não funcionando. dando nenhuma saída. meu comando fica assim: tail -f test.txt | stdbuf -oL grep 'aaa' | grep 'bbb' não está dando saída. Podes ajudar-me, por favor.
Sun

18

Normalmente, acho mais útil awkpara esse tipo de verificação lógica:

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

Testado com duas abas, uma na qual continuo escrevendo seq 20 >> myfilee a outra, por exemplo tail -f myfile | awk '/3/ && !/13/'.


15

Outra abordagem seria usar uma única grepinvocação em vez de duas e assim evitar o problema de buffer. Basta usar expressões regulares que correspondam a linhas que consistem em 0 ou mais caracteres que não sejam Y, depois um X e, em seguida, 0 ou mais que não Ys até o final da linha "

tail -f /path/to/log | grep '^[^Y]*X[^Y]*$'
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.