J'essaie d'exécuter une commande Shell depuis awk pour chaque ligne d'un fichier, et la commande Shell nécessite un argument d'entrée. J'ai essayé d'utiliser system()
, mais il n'a pas reconnu l'argument d'entrée.
Chaque ligne de ce fichier est l'adresse d'un fichier et je souhaite exécuter une commande pour traiter ce fichier. Donc, pour un exemple simple, je veux utiliser la commande 'wc' pour chaque ligne et passer $1
à wc.
awk '{system("wc $1")}' myfile
tu es proche. vous devez concaténer la ligne de commande avec des variables awk:
awk '{system("wc "$1)}' myfile
Vous ne pouvez pas récupérer la sortie d'un appel à awk system()
, vous pouvez uniquement obtenir le statut de sortie. Utilisez les constructions getline/pipe ou getline/variable/pipe
awk '{
cmd = "your_command " $1
while (cmd | getline line) {
do_something_with(line)
}
close(cmd)
}' file
Pour votre information, voici comment utiliser awk pour traiter les fichiers dont les noms sont stockés dans un fichier (fournissant une fonctionnalité similaire à wc dans cet exemple):
gawk '
NR==FNR { ARGV[ARGC++]=$0; next }
{ nW+=NF; nC+=(length($0) + 1) }
ENDFILE { print FILENAME, FNR, nW, nC; nW=nC=0 }
' file
Ce qui précède utilise GNU awk pour ENDFILE. Avec d’autres awks, stockez simplement les valeurs dans un tableau et imprimez-les en boucle dans la section END.
Ou utilisez le tuyau |
comme dans bash puis récupère la sortie dans une variable avec getline
de awk, comme ceci
zcat /var/log/fail2ban.log* | gawk '/.*Ban.*/ {print $7};' | sort | uniq -c | sort | gawk '{ "geoiplookup " $2 "| cut -f2 -d: " | getline geoip; print $2 "\t\t" $1 " " geoip}'
Cette ligne imprimera toutes les adresses IP interdites sur votre serveur avec leur origine (pays) à l'aide du paquet geoip-bin.
La dernière partie de cette ligne est celle qui nous concerne:
gawk '{ "geoiplookup " $2 "| cut -f2 -d: " | getline geoip; print $2 "\t\t" $1 " " geoip}'
Il dit simplement: lancez la commande "geoiplookup 182.193.192.4 | -f2 -d:"
($ 2 est substitué comme vous pouvez le deviner) et mettez le résultat de cette commande dans geoip (le | getline geoip
bit). Ensuite, imprimez quelque chose et quelque chose dans la variable geoip
.
L'exemple complet et les résultats peuvent être trouvés ici , un article que j'ai écrit.