Como aplicar um filtro à saída em tempo real de `tail -f`?


60
tail -f path

O exemplo acima produzirá modificações no arquivo instantaneamente, mas eu quero aplicar um filtro à saída, mostrado apenas quando houver uma palavra-chave xxx.

Como abordar isso?


11
Marcar as respostas como aceitas ajuda outras pessoas que leem suas perguntas e suas respostas a saber qual resposta pode ser mais provável de ajudá-las se tiverem uma pergunta ou problema semelhante. Você pode revisar suas perguntas anteriores clicando no seu nome de usuário.
Dennis Williamson

Respostas:


84

Com o Unix, você pode canalizar a saída de um programa para outro.

Então, para filtrar a cauda, ​​você pode usar o grep:

tail -f path | grep your-search-filter

Mas digamos que você tenha 100 linhas no final (final do arquivo), e essas linhas são as que você deseja filtrar. Sua solução
TraderJoeChicago 7/11

11
Se você deseja pesquisar apenas as últimas 100 linhas de um arquivo, tente tail -100 path | grep xxx
AddersUK

15

Resposta curta: tail -f somefile | grep somepattern

No entanto, isso tende a ficar aquém. Digamos que você esteja seguindo um arquivo rotacionado com frequência (se for um log de depuração, ele poderá ser rotacionado várias vezes). Nesse caso, tail -Fé seu amigo. Vou deixar você procurar a diferença.

Mas tail -fe tail -Fimprimir um monte de linhas em primeiro lugar, que é muitas vezes indesejável neste caso de uso, portanto, neste caso adicionar-n0

tail -F -n0 somefile | grep somepattern

Tudo bem, até que você queira fazer outra filtragem e tenha cuidado com o buffer. Por padrão, o stdout é buffer de linha ao gravar em um terminal, mas quando totalmente buffer ao gravar em um canal. Portanto, o seguinte emitirá linhas assim que forem encontradas, porque tailé explicitamente armazenado em buffer (ou libera sua saída no final de cada linha) e greptambém é armazenado em buffer porque sua saída está indo para o seu terminal:

tail -F -n0 somefile | grep somepattern

Mas então você decide usar algo como awkou cutprocessar ainda mais a saída.

tail -F -n0 somefile | grep somepattern | awk '{print $3}'

E agora você se pergunta para onde foi a sua saída ... dependendo do volume de logs, pode achar que obtém saída, mas será uma página de cada vez, porque agora o stdout grepestá operando de maneira totalmente com buffer, e assim awkrecebe 4kB de cada vez (por padrão).

Nesse caso, você pode dizer greppara sempre tornar a linha stdout armazenada em buffer usando a --line-bufferedopção

tail -F -n0 somefile | grep --line-buffered somepattern | ...

No entanto, a maioria dos comandos não possui um análogo --line-buffered. No caso de ferramentas com mais scripts, você pode usar uma função para liberar a saída (por exemplo awk, in , a função is fflush(), que compartilha o mesmo nome que seu equivalente em C, ferramentas como Perl e Python têm algo semelhante).

Com pessoas como essa, cutvocê provavelmente está sem sorte; ... mas você pode tentar procurar unbuffer, o que acho que é algo fornecido pela expectcadeia de ferramentas (nunca a usei).

Espero que você tenha achado isso útil.

Cheers, Cameron


Eu realmente aprecio a explicação de por que isso funciona no modo de buffer de linha. Essa é uma excelente visão, obrigado.
Verde

2

e você pode usar vários pipes e greps e excluir itens com grep -v, obter insensibilidade de maiúsculas e minúsculas com grep -i, etc.

ou seja: tail -100f / var / log / messages | grep -V ACPI | grep -i ata

comece a alinhar 100 linhas a partir do final e mantenha a cauda, ​​primeiro exclua todas as linhas com ACPI, depois mostre linhas com ata, ATA ou qualquer combinação delas.

Outra prática são as opções ABC, para as linhas Depois, Antes e Contexto (linhas antes e depois).

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.