O comando sed
, o comando awk
e a remoção do período final podem ser combinados em um único 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}'
Ou, como se espalha em várias linhas:
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}'
Como o comando awk
segue a instrução done
, apenas um awk
process é chamado. Embora a eficiência possa não importar aqui, isso é mais eficiente do que criar um novo processo sed ou awk com cada loop.
Exemplo
Com este arquivo de teste:
$ cat hostlist.txt
www.google.com
fd-fp3.wg1.b.yahoo.com
O comando produz:
$ 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
Como funciona
awk lê implicitamente sua entrada um registro (linha) de cada vez. Este script awk usa uma única variável, f
, que indica se a linha anterior era um cabeçalho de seção de resposta ou não.
-
f{sub(/.$/,"",$1); print $1", "$NF; f=0}
Se a linha anterior era um cabeçalho de seção de resposta, então
f
será true e os comandos em chaves serão executados. O primeiro remove o período final do primeiro campo. O segundo imprime o primeiro campo, seguido por,
, seguido pelo último campo. A terceira instrução redefinef
para zero (falso).Em outras palavras,
f
aqui funciona como uma condição lógica. Os comandos em chaves são executados sef
for diferente de zero (que, em awk, significa 'true'). -
/ANSWER SECTION/{f=1}
Se a linha atual contiver a string
ANSWER SECTION
, a variávelf
será definida como1
(true).Aqui,
/ANSWER SECTION/
serve como uma condição lógica. Ele é avaliado como verdadeiro se a corrente corresponder à expressão regularANSWER SECTION
. Em caso afirmativo, o comando em chaves é executado.