usando awk ao invés de grep:
awk '/string1/ { print >> "output1.log" ; fflush() }
/string2/ { print >> "output2.log" ; fflush() }
/string3/ { print >> "output3.log" ; fflush() }' input.log
Isso gera all linhas correspondentes aos seus respectivos arquivos output.log. Isso porque não consigo entender seus requisitos tail -f
e tail -n 1
conflitantes. Se você realmente quiser que ele comece a seguir input.log
da última linha atual, canalize tail -f -n 1
no script awk
e livre-se do input.log
no final da linha. por exemplo,
tail -f -n 1 input.log | awk '...same awk script as above...'
Você também pode fazer isso com tee
e grep
e substituição de processo
(mas será visivelmente mais lento):
tee >(grep --line-buffered string1 >> output1.log) \
>(grep --line-buffered string2 >> output2.log) \
>(grep --line-buffered string3 >> output3.log) < input.log
ou
tail -f -n 1 input.log | tee .....
OBSERVAÇÃO: A fflush()
na solução awk
e a opção --line-buffered
na solução tee
são necessárias apenas se você estiver canalizando a saída de tail -f
( ou algum outro processo interminável) em awk
ou tee
.
Sem eles, os arquivos de saída só serão gravados quando os buffers de saída (de awk ou grep) estiverem cheios - e se o trabalho for abortado enquanto houver saída não escrita nos buffers (por exemplo, pressionando Ctrl-C) a saída ainda nos buffers será perdida.
Com eles, ambas as soluções rodam muito mais devagar (porque elas liberam a saída a cada gravação) - mas é improvável que seja significativo, exceto com arquivos de entrada muito grandes.
BTW, isso não é um problema quando a entrada termina - nesse caso, tanto o awk quanto o grep liberam automaticamente seus buffers de saída antes de sair.
Outra alternativa seria executar o pipe em awk
(ou tee
) em um sub-shell que aprisionou e ignorou o sinal de interrupção do Ctrl-C. por exemplo,
tail -f input.log | (
trap '' INT
awk '/string1/ { print >> "output1.log" }
/string2/ { print >> "output2.log" }
/string3/ { print >> "output3.log" }'
)
O tail -f
é afetado (morto) pressionando Ctrl-C, mas o sub-shell executando awk
o ignora. awk
libera seus buffers de saída e sai quando o tail
é eliminado porque sua entrada foi concluída.
Veja Armadilha Ctrl-C no script do awk para outro exemplo / explicação.
Se você não quiser que ele siga o arquivo de log, não use a opção tail
-f
.
Use apenas tail -n 1 | .....
ou veja a resposta de Guy, que imprime a última correspondência das três strings em seus respectivos arquivos de saída.