Existe um comando que combina `tee` e `grep` de forma que em um pipeline a parte tee possa direcionar correspondências para um arquivo?

Existe um comando que combina `tee` e `grep` de forma que em um pipeline a parte tee possa direcionar correspondências para um arquivo?

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 | grepsessõ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 teee grepde 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 taila produção de dados para o primeiro teeno pipeline. Isso teeduplicaria os dados e enviaria uma cópia para a próxima teee a outra para uma substituição de processo. Essa substituição de processo seria executada grepnos dados que chegam teee 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, awkou sedpodem 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 wcomando in sedsempre 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'

informação relacionada