Quero pesquisar em um arquivo de log (em tempo real) o conteúdo de msg = "yxyxyx" e, em seguida, gravar os valores exclusivos em outfile.txt
Eu escrevi isto:
tail -f /var/log/firewall.log | sed -n '/msg=/{s/.*msg=//;s/\S*=.*//;p}' | awk '!seen[$0]++' >> outfile.txt
Outfile é criado, mas vazio. Está escrevendo perfeitamente no console sem a parte >> outfile.txt.
Obrigado!
Responder1
você poderia usar stdbuf -oL ou stdbuf -o0 antes do comando awk como abaixo;
tail -f firewall.log | sed -nu '/msg=/{s/.*msg=//;s/\S*=.*//;p}' | stdbuf -oL awk '!seen[$0]++' >> outfile.txt
tail -f firewall.log | sed -nu '/msg=/{s/.msg=//;s/\S=.*//;p}' | stdbuf -o0 awk '!visto[$0]++' >> outfile.txt
homem sed;
-você, --sem buffer
carregue quantidades mínimas de dados dos arquivos de entrada e libere os buffers de saída com mais frequência
homem stdbuf;
stdbuf - Executa COMMAND, com operações de buffer modificadas para seus fluxos padrão.
-o, --output=MODE ajusta o buffer do fluxo de saída padrão
Se MODE for 'L', o fluxo correspondente será armazenado em buffer de linha. Esta opção é inválida com entrada padrão.
Se MODE for '0', o fluxo correspondente não será armazenado em buffer.
Por exemplo;
primeiro execute isso;
user@h$ tail -f firewall.log | sed -nu '/msg=/{s/.*msg=//;s/\S*=.*//;p}' | stdbuf -oL awk '!seen[$0]++' >> outfile.txt
execute este outro terminal; echo msg="1" >> firewall.log
, saída conforme abaixo;
user@h$ tail -f firewall.log | sed -nu '/msg=/{s/.*msg=//;s/\S*=.*//;p}' | stdbuf -oL awk '!seen[$0]++' >> outfile.txt
user@host$ cat outfile.txt
1
execute novamente o mesmo echo msg="1" >> firewall.log
, a saída não é alterada;
Depois de executar isto; echo msg="2" >> firewall.log
, saída conforme abaixo;
user@host$ tail -f firewall.log | sed -nu '/msg=/{s/.*msg=//;s/\S*=.*//;p}' | stdbuf -oL awk '!seen[$0]++' >> outfile.txt
user@host$ cat outfile.txt
1
2