Como cortar sem buffer?

8

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.

Forkbeard
fonte
awk -F'[><@]' '/@xyz.nl/ {print $2}'...
jasonwryan
1
tente grep -oP '[^<]+([email protected])'(juntamente com suas outras opções grep conforme necessário)
Sundeep
As opções awk e grep acima funcionam como um encanto!
Forkbeard

Respostas:

16

Se você estiver em um sistema usando o GNU Coreutils (quase qualquer Linux), você pode tentar stdbuf:

… | stdbuf -oL cut -d '@' -f 1 | …

-oL torna a linha em buffer, que parece o que você deseja.

derobert
fonte
Era exatamente isso que eu procurava, obrigado!
Forkbeard
Não muda nada para mim por algum motivo. :(
panzi
1
@panzi Sinta-se à vontade para fazer sua própria pergunta, vinculando a esta. Por favor, inclua detalhes completos (comando exato que você está executando, se possível, sistema operacional, distribuição e versão etc.) Esperemos que alguém seja capaz de descobrir por que isso não funciona para você.
21817 derobert