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

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

Estou seguindo um arquivo de log com o sinalizador -f. Então estou canalizando isso para o 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 pipe, o arquivo para de ser atualizado e parece que nenhum dado está 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?

Responder1

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

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

Caso grepnão tenha essa opção, você pode usar stdbufcomo alternativa:

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

Responder2

Normalmente acho mais útil awkesse tipo de verificação lógica:

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

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

Responder3

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 diferentes de Y, depois um X e, em seguida, 0 ou mais caracteres diferentes de Y novamente até o final da linha"

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

informação relacionada