Eu tenho um arquivo chamado hostlist.txt
que contém texto como este:
host1.mydomain.com
host2.mydomain.com
anotherhost
www.mydomain.com
login.mydomain.com
somehost
host3.mydomain.com
Eu tenho o seguinte pequeno script:
#!/usr/local/bin/bash
while read host; do
dig +search @ns1.mydomain.com $host ALL \
| sed -n '/;; ANSWER SECTION:/{n;p;}';
done <hostlist.txt \
| gawk '{print $1","$NF}' >fqdn-ip.csv
Qual saída para fqdn-ip.csv
:
host1.mydomain.com.,10.0.0.1
host2.mydomain.com.,10.0.0.2
anotherhost.internal.mydomain.com.,10.0.0.11
www.mydomain.com.,10.0.0.10
login.mydomain.com.,10.0.0.12
somehost.internal.mydomain.com.,10.0.0.13
host3.mydomain.com.,10.0.0.3
Minha pergunta é como removo o .
antes da vírgula sem chamar sed
ou gawk
novamente? Existe uma etapa que eu possa executar nas chamadas existentes sed
ou gawk
que reduzirão o ponto?
hostlist.txt
conterá milhares de hosts, por isso quero que meu script seja rápido e eficiente.
shell-script
awk
sed
regular-expression
string
Linoob
fonte
fonte
dig +short
não funciona para você?Respostas:
O
sed
comando, oawk
comando e a remoção do período final podem ser combinados em um único comando awk:Ou, como distribuídos por várias linhas:
Porque o
awk
comando segue adone
instrução, apenas umawk
processo é chamado. Embora a eficiência possa não ter importância aqui, isso é mais eficiente do que criar um novo processo sed ou awk a cada loop.Exemplo
Com este arquivo de teste:
O comando produz:
Como funciona
O awk lê implicitamente sua entrada, um registro (linha) de cada vez. Esse script do awk usa uma única variável,
f
que indica se a linha anterior era ou não um cabeçalho da seção de resposta.f{sub(/.$/,"",$1); print $1", "$NF; f=0}
Se a linha anterior era um cabeçalho da seção de resposta,
f
será verdadeira e os comandos entre chaves são executados. O primeiro remove o período à direita do primeiro campo. O segundo imprime o primeiro campo, seguido por,
, seguido pelo último campo. A terceira instrução é redefinidaf
para zero (false).Em outras palavras,
f
aqui funciona como uma condição lógica. Os comandos entre chaves são executados sef
for diferente de zero (o que, no awk, significa 'true')./ANSWER SECTION/{f=1}
Se a linha atual contiver a sequência
ANSWER SECTION
, a variávelf
será configurada como1
(true).Aqui,
/ANSWER SECTION/
serve como uma condição lógica. É avaliado como verdadeiro se a corrente corresponder à expressão regularANSWER SECTION
. Se isso acontecer, o comando entre chaves será executado.fonte
f
uma variável arbitrária ou éf{}
uma parte explícita da funcionalidade do awk?f
é uma variável arbitrária. Você pode realmente colocar antes das{}
complexas condições lógicas.f
é apenas uma condição lógica muito simples: é verdadeira se diferente de zero, falsa se zero./ANSWER SECTION/
desempenha o papel de condição lógica, análogo ao papelf
desempenhado no primeiro comando. Atualizei a resposta para discutir isso.dig
pode ler em um arquivo que contém uma lista de nomes de host e processá-los um por um. Você também pode dizerdig
para suprimir toda a saída, exceto a seção de resposta.Isso deve fornecer a saída desejada:
awk
Asub()
função de é usada para retirar o período literal.
do final do primeiro campo. Entãoawk
imprime os campos 1 e 5 separados por vírgula.NOTA: entradas em
hostlist.txt
que não são resolvidas são completamente descartadas - elas não aparecem no stdout OU no stderr.(Testado no Linux e FreeBSD)
fonte
Altere sua chamada de
gawk
para o seguinte:fonte