Estou tentando extrair várias partes de um arquivo ou, pelo menos, observar as partes em um arquivo de log, caso elas ocorram, mas não quero configurar várias tail | grep
sessões. Em vez disso, gostaria apenas de acompanhar a saída de cada grep.
Suponho que poderia fazer isso com awk
, mas talvez já exista algo mais próximo dessa ideia.
Por exemplo, o comando pode ser parecido com isto:
tail -f /var/log/syslog | teegrep cron1 -f CRON | teegrep cloud-init2 -f CLOUD-INIT
A saída seriam os arquivos CRON e CLOUD-INIT, enquanto tudo iria para stdout no final. Somente as correspondências para as linhas 'cron1' e 'cloud-init2' acabariam em seus respectivos arquivos.
Talvez já faça parte de um comando e eu simplesmente não saiba disso. Ou possivelmente apenas alguns truques do bash/zsh que fariam a mesma coisa. De qualquer maneira: existe um comando que combina tee
e grep
de forma que em um pipeline a parte tee possa direcionar correspondências para um arquivo?
Responder1
Assumindo um shell com substituições de processo >(...)
,:
tail -f /var/log/syslog |
tee >(grep cron1 >CRON) |
tee >(grep cloud-init2 >CLOUD-INIT)
Isso causaria tail
a produção de dados para o primeiro tee
no pipeline. Isso tee
duplicaria os dados e enviaria uma cópia para a próxima tee
e a outra para uma substituição de processo. Essa substituição de processo seria executada grep
nos dados que chegam tee
e o resultado iria para o arquivo CRON
.
A última etapa do pipeline funcionaria de maneira semelhante.
Em um shell onde as substituições de processos não estão disponíveis, por exemplo /bin/sh
, awk
ou sed
podem ser usadas.
Com awk
:
tail -f /var/log/syslog |
awk '{ print }
/cron1/ { print >"CRON" }
/cloud-print/ { print >"CLOUD-INIT" }'
Com sed
(observe que temos que ter certeza de que os arquivos de saída não existem, já que o w
comando in sed
sempre anexa dados a um arquivo):
rm -f CLOUD CLOUD-INIT
tail -f /var/log/syslog |
sed -e '/cloud/w CLOUD' \
-e '/cloud-print/w CLOUD-INIT'