J'ai un fichier appelé hostlist.txt
qui contient du texte comme celui-ci:
host1.mydomain.com
host2.mydomain.com
anotherhost
www.mydomain.com
login.mydomain.com
somehost
host3.mydomain.com
J'ai le petit script suivant:
#!/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
Quels résultats pour 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
Ma question est de savoir comment supprimer le .
juste avant la virgule sans invoquer sed
ou à gawk
nouveau? Existe-t-il une étape que je peux effectuer dans les appels existants sed
ou gawk
qui supprimera le point?
hostlist.txt
contiendra des milliers d'hôtes donc je veux que mon script soit rapide et efficace.
dig +short
ça ne marche pas pour vous?Réponses:
La
sed
commande, laawk
commande et la suppression de la période de fin peuvent toutes être combinées en une seule commande awk:Ou, comme étalé sur plusieurs lignes:
Étant donné que la
awk
commande suit l'done
instruction, un seulawk
processus est appelé. Bien que l'efficacité puisse ne pas avoir d'importance ici, c'est plus efficace que de créer un nouveau processus sed ou awk avec chaque boucle.Exemple
Avec ce fichier de test:
La commande produit:
Comment ça fonctionne
awk lit implicitement son entrée un enregistrement (ligne) à la fois. Ce script awk utilise une seule variable,
f
qui indique si la ligne précédente était un en-tête de section de réponse ou non.f{sub(/.$/,"",$1); print $1", "$NF; f=0}
Si la ligne précédente était un en-tête de section de réponse, alors ce
f
sera vrai et les commandes entre accolades seront exécutées. Le premier supprime la période de fin du premier champ. Le second imprime le premier champ, suivi de,
, suivi du dernier champ. La troisième instruction est remisef
à zéro (faux).En d'autres termes,
f
ici fonctionne comme une condition logique. Les commandes entre accolades sont exécutées sif
est différent de zéro (ce qui, en awk, signifie «vrai»)./ANSWER SECTION/{f=1}
Si la ligne actuelle contient la chaîne
ANSWER SECTION
, la variablef
est définie sur1
(true).Ici,
/ANSWER SECTION/
sert de condition logique. Il évalue à vrai si le courant correspond à l'expression régulièreANSWER SECTION
. Si c'est le cas, la commande entre accolades est exécutée.la source
f
une variable arbitraire ou faitf{}
-elle explicitement partie des fonctionnalités de awk?f
est une variable arbitraire. Vous pouvez réellement mettre avant les{}
conditions logiques complexes.f
est juste une condition logique très simple: elle est vraie si non nulle, fausse si nulle./ANSWER SECTION/
joue le rôle de condition logique, analogue au rôlef
joué dans la première commande. J'ai mis à jour la réponse pour en discuter.dig
peut lire un fichier contenant une liste de noms d'hôtes et les traiter un par un. Vous pouvez également demanderdig
de supprimer toutes les sorties à l'exception de la section des réponses.Cela devrait vous donner le résultat souhaité:
awk
Lasub()
fonction de 'est utilisée pour supprimer la période littérale.
de la fin du premier champ.awk
Imprime ensuite les champs 1 et 5 séparés par une virgule.REMARQUE: les entrées
hostlist.txt
qui ne sont pas résolues sont complètement ignorées - elles n'apparaissent pas sur stdout OU stderr.(Testé sur Linux et FreeBSD)
la source
Modifiez votre invocation de
gawk
comme suit:la source