Il sedcomando, il awkcomando e la rimozione del periodo finale possono essere combinati in un unico comando awk:
while read -r host; do dig +search "$host" ALL; done <hostlist.txt | awk 'f{sub(/.$/,"",$1); print $1", "$NF; f=0} /ANSWER SECTION/{f=1}'
Oppure, come distribuito su più righe:
while read -r host
do
dig +search "$host" ALL
done <hostlist.txt | awk 'f{sub(/.$/,"",$1); print $1", "$NF; f=0} /ANSWER SECTION/{f=1}'
Poiché il awkcomando segue l' doneistruzione, awkviene richiamato un solo processo. Anche se l'efficienza può non avere importanza qui, è più efficiente della creazione di un nuovo processo sed o awk con ogni ciclo.
Esempio
Con questo file di prova:
$ cat hostlist.txt
www.google.com
fd-fp3.wg1.b.yahoo.com
Il comando produce:
$ while read -r host; do dig +search "$host" ALL; done <hostlist.txt | awk 'f{sub(/.$/,"",$1); print $1", "$NF; f=0} /ANSWER SECTION/{f=1}'
www.google.com, 216.58.193.196
fd-fp3.wg1.b.yahoo.com, 206.190.36.45
Come funziona
awk legge implicitamente il suo input un record (riga) alla volta. Questo script awk utilizza una singola variabile, fche indica se la riga precedente era un'intestazione della sezione di risposta o meno.
f{sub(/.$/,"",$1); print $1", "$NF; f=0}
Se la riga precedente era un'intestazione della sezione di risposta, allora fsarà vera e verranno eseguiti i comandi tra parentesi graffe. Il primo rimuove il periodo finale dal primo campo. Il secondo stampa il primo campo, seguito da ,, seguito dall'ultimo campo. La terza istruzione viene reimpostata fsu zero (false).
In altre parole, fqui funziona come una condizione logica. I comandi tra parentesi graffe vengono eseguiti se fè diverso da zero (che, in awk, significa "vero").
/ANSWER SECTION/{f=1}
Se la riga corrente contiene la stringa ANSWER SECTION, la variabile fè impostata su 1(true).
Qui, /ANSWER SECTION/serve come condizione logica. Valuta vero se la corrente corrisponde all'espressione regolare ANSWER SECTION. In tal caso, il comando tra parentesi graffe viene eseguito.
dig +shortnon funziona per te?