Voglio ottenere solo gli indirizzi e-mail che terminano in "@ xyz.nl" dal mio file di registro della posta. Per raggiungere questo obiettivo faccio:
# tail -f /var/log/mail.log | grep --i --line-buffered "@xyz.nl" | cut -d '@' -f 1 | cut -d '<' -f 2
--Line-buffered with grep è necessario perché altrimenti bufferizzerà il suo output perché il pipe non è considerato un terminale. Grep produrrà linee come queste:
Aug 29 11:56:01 localhost postfix/smtp[4124]: 05491500123: to=<someone@xyz.nl>, 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)
Il primo taglio quindi effettua:
Aug 29 11:56:01 localhost postfix/smtp[4124]: 05491500123: to=<someone
Il secondo taglio dovrebbe generare:
someone
Tuttavia, sembra che anche il taglio sia buffering. Se avvio il comando con cat anziché tail -f ottengo tutti i risultati rilevanti (nel formato preferito) dal file di registro. Ma ho bisogno dei risultati dal file di registro in tempo reale.
Ho provato a usare unbuffer per questo:
# tail -f /var/log/mail.log | grep --i --line-buffered "@xyz.nl" | unbuffer cut -d '@' -f 1 | cut -d '<' -f 2
Ho anche provato:
# unbuffer tail -f /var/log/mail.log | grep --i --line-buffered "@xyz.nl" | unbuffer cut -d '@' -f 1 | cut -d '<' -f 2
... che dovrebbe rimuovere il buffering 4K dal primo taglio . Tuttavia, questo non funziona. So che è il buffering perché se eseguo grep per il nostro dominio locale ottiene molti più hit, il buffer viene riempito prima e l'output viene generato prima (in batch 4K).
Quindi la mia domanda è: come taglio senza buffer ?
Correlati: So che sed e (g) awk possono fornirmi gli indirizzi e-mail. Ci ho provato ma non ho ancora ottenuto alcun risultato. Le risposte che usano sed o (g) awk sono benvenute e possono risolvere il mio problema diretto, ma rimango interessato alla risposta nominale della domanda su come annullare il buffering del comando cut. Il comando cut non parla di (un) buffering.
grep -oP '[^<]+(?=@xyz.nl)'
(insieme alle altre opzioni grep se necessario)
awk -F'[><@]' '/@xyz.nl/ {print $2}'
...