Desejo obter apenas endereços de email que terminem em "@ xyz.nl" do meu arquivo de log de mensagens. Para conseguir isso, eu faço:
# tail -f /var/log/mail.log | grep --i --line-buffered "@xyz.nl" | cut -d '@' -f 1 | cut -d '<' -f 2
O --line-buffered com grep é necessário porque, de outra forma, armazenará em buffer sua saída porque o pipe não é considerado um terminal. O Grep produzirá linhas como estas:
Aug 29 11:56:01 localhost postfix/smtp[4124]: 05491500123: to=<[email protected]>, relay=123.456.123.456[123.456.123.456]:25, delay=2, delays=0.4/0/0.4/1.2, dsn=2.0.0, status=sent (250 2.0.0 u7T9twxN074009 Message accepted for delivery)
O primeiro corte faz então:
Aug 29 11:56:01 localhost postfix/smtp[4124]: 05491500123: to=<someone
O segundo corte deve gerar:
someone
No entanto, parece que o corte também é amortecedor. Se eu iniciar o comando com cat, em vez de tail -f , obterá todos os resultados relevantes (no formato preferido) do arquivo de log. Mas preciso dos resultados do arquivo de log em tempo real.
Eu tentei usar o buffer para isso:
# tail -f /var/log/mail.log | grep --i --line-buffered "@xyz.nl" | unbuffer cut -d '@' -f 1 | cut -d '<' -f 2
Também tentei:
# unbuffer tail -f /var/log/mail.log | grep --i --line-buffered "@xyz.nl" | unbuffer cut -d '@' -f 1 | cut -d '<' -f 2
... que deve remover o buffer 4K do primeiro corte . No entanto, isso não funciona. Eu sei que é um buffer porque, se eu grep para o nosso domínio local, obtém muito mais hits, o buffer é preenchido mais cedo e a saída é gerada mais cedo (em lotes de 4K).
Então, minha pergunta é: como faço para cortar o buffer ?
Relacionado: Eu sei que sed e (g) awk podem entregar os endereços de email para mim. Eu tenho tentado, mas até agora sem nenhum resultado. Respostas usando sed ou (g) awk são bem-vindas e podem resolver meu problema direto, mas continuo interessado na resposta nominal da pergunta como descomprimir o comando cut. O comando cut não fala em (des) buffering.
awk -F'[><@]' '/@xyz.nl/ {print $2}'
...grep -oP '[^<]+([email protected])'
(juntamente com suas outras opções grep conforme necessário)Respostas:
Se você estiver em um sistema usando o GNU Coreutils (quase qualquer Linux), você pode tentar
stdbuf
:-oL
torna a linha em buffer, que parece o que você deseja.fonte