Je veux exécuter la commande system
dans un script awk et obtenir sa sortie stockée dans une variable. J'ai essayé de le faire, mais la sortie de la commande va toujours au Shell et je ne suis pas en mesure de la capturer. Des idées sur la façon dont cela peut être fait?
Exemple:
$ date | awk --field-separator=! {$1 = system("strip $1"); /*more processing*/}
Doit appeler la commande système strip
et au lieu d'envoyer la sortie au shell, doit la renvoyer à $1
pour plus de traitement. Rignt maintenant, il envoie la sortie à Shell et attribue le retcode de la commande à $1
.
Compris.
Nous utilisons les awk's E/S bidirectionnelles
{
"strip $1" |& getline $1
}
passe 1 $ à supprimer et la ligne de lecture reprend la sortie de la bande à 1 $
Remarque: Coprocess est GNU spécifique à awk. Quoi qu'il en soit, une autre alternative utilise getline
cmd = "strip "$1
while ( ( cmd | getline result ) > 0 ) {
print result
}
close(cmd)
L'appel de close(cmd)
empêchera awk
de renvoyer cette erreur après un certain nombre d'appels:
fatal: impossible d'ouvrir le tube `... '(Trop de fichiers ouverts)
Pour exécuter une commande système dans awk
, vous pouvez utiliser system()
ou cmd | getline
.
Je préfère cmd | getline
Car il vous permet d'attraper la valeur dans une variable:
$ awk 'BEGIN {"date" | getline mydate; close("date"); print "returns", mydate}'
returns Thu Jul 28 10:16:55 CEST 2016
Plus généralement, vous pouvez définir la commande dans une variable:
awk 'BEGIN {
cmd = "date -j -f %s"
cmd | getline mydate
close(cmd)
}'
Notez qu'il est important d'utiliser close()
pour éviter d'obtenir une erreur "crée trop de fichiers ouverts" si vous avez plusieurs résultats (merci mateuscb pour l'avoir signalé dans les commentaires).
En utilisant system()
, la sortie de la commande est imprimée automatiquement et la valeur que vous pouvez saisir est son code retour:
$ awk 'BEGIN {d=system("date"); print "returns", d}'
Thu Jul 28 10:16:12 CEST 2016
returns 0
$ awk 'BEGIN {d=system("ls -l asdfasdfasd"); print "returns", d}'
ls: cannot access asdfasdfasd: No such file or directory
returns 2
gawk '{dt=substr($4,2,11); gsub(/\//," ",dt); "date -d \""dt"\" +%s"|getline ts; print ts}'
Vous pouvez l'utiliser lorsque vous devez traiter une sortie grep:
echo "some/path/exex.c:some text" | awk -F: '{ "basename "$1"" |& getline $1; print $1 " ==> " $2}'
option -F:
dire à awk d'utiliser :
comme séparateur de champ
"basename "$1""
exécute la commande Shell basename
sur le premier champ
|& getline $1
lit la sortie de la précédente commande Shell dans le sous-flux
output:
exex.c ==> some text