web-dev-qa-db-fra.com

Comment puis-je passer des variables d'awk à une commande Shell?

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
41
Vahid Mirjalili

tu es proche. vous devez concaténer la ligne de commande avec des variables awk:

awk '{system("wc "$1)}' myfile
57
Kent

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
40
glenn jackman

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.

2
Ed Morton

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.

0
ychaouche