É possível usar grep
em um fluxo contínuo?
O que quero dizer é uma espécie de tail -f <file>
comando, mas com grep
a saída para manter apenas as linhas que me interessam.
Eu tentei, tail -f <file> | grep pattern
mas parece que grep
só pode ser executado quando tail
terminar, ou seja, nunca.
tail -f file
obras (I ver a nova saída em tempo real)Respostas:
Ative o
grep
modo de buffer de linha ao usar o BSD grep (FreeBSD, Mac OS X etc.)Você não precisa fazer isso no GNU grep (usado em praticamente qualquer Linux), pois ele será liberado por padrão (YMMV para outros gostos de Unix, como SmartOS, AIX ou QNX).
fonte
strace
. Sem o--line-buffered
, não vai funcionar.tail -f | grep
e o--line-buffered
resolve para mim (no Ubuntu 14.04, GNU grep versão 2.16). Onde está a lógica "usar buffer de linha se stdout é um tty" implementada? Em git.savannah.gnu.org/cgit/grep.git/tree/src/grep.c ,line_buffered
é definido apenas pelo analisador de argumentos.--line-buffered
eu não tenho saída. No entanto, após o teste, parece que o GNU grep faz o que você descreve. Assim como a maioria das coisas do Unix, isso depende da implementação da sua plataforma. Como a pergunta não especificou plataforma, suas informações parecem falsas - após revisar o código do BSD grep e compará-lo ao GNU grep, o comportamento é definitivamente controlado pela opção --line-buffered. É que apenas o GNU grep é liberado por padrão.Eu uso
tail -f <file> | grep <pattern>
o tempo todo.Esperará até que o grep seja liberado, não até que termine (estou usando o Ubuntu).
fonte
Eu acho que o seu problema é que o grep usa algum buffer de saída. Tentar
ele definirá o modo de buffer de saída do grep como sem buffer.
fonte
grep
.unbuffer
(noexpect-dev
pacote debian) é rei . Então, eu usaria unbuffer sobre stdbuf.top
com stdbuf e unbuffer). E realmente não existe uma solução 'mágica': o buffer do buffer também falha algumas vezes, por exemplo, o awk usa uma implementação de buffer diferente (o stdbuf também falha).stdbuf
, `unbuffer e tamponamento stdio em pixelbeat.org/programming/stdio_bufferingSe você deseja encontrar correspondências no arquivo inteiro (não apenas no final) e deseja que ele fique aguardando novas correspondências, isso funciona perfeitamente:
O
-c +0
sinalizador diz que a saída deve iniciar0
bytes (-c
) desde o início (+
) do arquivo.fonte
Na maioria dos casos, você pode
tail -f /var/log/some.log |grep foo
e funcionará bem.Se você precisar usar vários greps em um arquivo de log de execução e você achar que você tem nenhuma saída, pode ser necessário furar o
--line-buffered
interruptor em seu meio grep (s), assim:fonte
você pode considerar esta resposta como aprimoramento .. geralmente estou usando
-F é melhor no caso de rotação do arquivo (-f não funcionará corretamente se o arquivo for girado)
-A e -B é útil para obter linhas imediatamente antes e após a ocorrência do padrão. Esses blocos aparecerão entre os separadores de linhas tracejadas
Mas para mim eu prefiro fazer o seguinte
isso é muito útil se você deseja pesquisar dentro de logs transmitidos. Quero dizer, voltar e avançar e olhar profundamente
fonte
grep -C 3 <pattern>
, substitui -A <N> e -B <N> se N for o mesmo.Não vi ninguém oferecer o meu aval habitual para isso:
Eu prefiro isso, porque você pode usar
ctrl + c
para parar e navegar pelo arquivo sempre que quiser e depois pressionarshift + f
para retornar à pesquisa de transmissão ao vivo.fonte
sed seria uma escolha melhor ( editor de stream )
tail -n0 -f <file> | sed -n '/search string/p'
e, se você quiser que o comando tail saia, depois de encontrar uma sequência específica:
tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'
Obviamente, um basismo: $ BASHPID será o ID do processo do comando tail. O comando sed é o próximo após a cauda no pipe, portanto, o ID do processo sed será $ BASHPID + 1.
fonte
$BASHPID+1
) será seu é falsa em muitas situações, e isso não ajuda a resolver o problema de buffer, que é provavelmente o que o OP estava tentando perguntar. Em particular, recomendandosed
ao longogrep
aqui parece ser apenas uma questão de preferência (duvidosa). (Você pode obterp;q
comportamento comgrep -m 1
se esse é o ponto que você está tentando entregar.)--line-buffered
não. Eu sinceramente não entendo a menos 1.Sim, isso realmente funcionará bem.
Grep
e a maioria dos comandos Unix opera em fluxos uma linha por vez. Cada linha que sai da cauda será analisada e transmitida se corresponder.fonte
grep
for o último comando na cadeia de tubulação, ele funcionará como você explica. No entanto, se estiver no meio, ele armazenará em buffer cerca de 8k de saída por vez.Este comando funciona para mim (Suse):
coletando logons no serviço de correio
fonte
você certamente não terá sucesso com
quando você usa "colortail" como um pseudônimo para cauda, por exemplo. na festança
você pode verificar por tipo de alias se isso gera algo como tail isan alias of
colortail -n 30
. então você tem o seu culpado :)Solução:
remova o alias com
verifique se você está usando o binário real 'real' por este comando
que deve gerar algo como:
e então você pode executar seu comando
Boa sorte.
fonte
Use awk (outro ótimo utilitário bash) em vez de grep, onde você não tem a opção de buffer de linha! Ele transmitirá continuamente seus dados da cauda.
é assim que você usa grep
É assim que você usaria o awk
fonte
{print $0}
é redundante, como impressão, é a acção padrão quando uma condição passa.)