J'ai un programme en C que je veux appeler en utilisant awk dans les scripts Shell. Comment puis-je faire quelque chose comme ça?
De la page de manuel AWK:
système (cmd) exécute cmd et renvoie son état de sortie
Le GNU AWK manuel a aussi ne section qui décrit en partie la fonction system
et fournit un exemple:
system("date | mail -s 'awk run done' root")
Il y a plusieurs façons.
awk a une fonction system()
qui exécutera une commande shell:
system("cmd")
Vous pouvez imprimer sur un tuyau:
print "blah" | "cmd"
Vous pouvez avoir des commandes de construction awk et diriger toute la sortie vers le shell:
awk 'some script' | sh
Quelque chose d'aussi simple que cela fonctionnera
awk 'BEGIN{system("echo hello")}'
et
awk 'BEGIN { system("date"); close("date")}'
#!/usr/bin/awk -f
BEGIN {
command = "ls -lh"
command |getline
}
Lance "ls -lh" dans un script awk
Cela dépend vraiment :) L'un des utilitaires Linux les plus utiles (info coreutils
) est xargs
. Si vous utilisez awk
, vous avez probablement un cas d'utilisation plus complexe à l'esprit - votre question n'est pas très détaillée.
printf "1 2\n3 4" | awk '{ print $2 }' | xargs touch
Va exécuter touch 2 4
. Ici touch
pourrait être remplacé par votre programme. Plus d'infos sur info xargs
et man xargs
(vraiment, lis ces ). Je crois que vous voudriez remplacer touch
par votre programme.
Ventilation du script précédent:
printf "1 2\n3 4"
# Output:
1 2
3 4
# The pipe (|) makes the output of the left command the input of
# the right command (simplified)
printf "1 2\n3 4" | awk '{ print $2 }'
# Output (of the awk command):
2
4
# xargs will execute a command with arguments. The arguments
# are made up taking the input to xargs (in this case the output
# of the awk command, which is "2 4".
printf "1 2\n3 4" | awk '{ print $2 }' | xargs touch
# No output, but executes: `touch 2 4` which will create (or update
# timestamp if the files already exist) files with the name "2" and "4"
Mise à jour Dans la réponse d'origine, j'ai utilisé echo
à la place de printf
. Cependant, printf
est l'alternative meilleure et plus portable, comme l'a souligné un commentaire (où d'excellents liens avec des discussions peuvent être trouvés).
Une méthode beaucoup plus robuste consisterait à utiliser la fonction getline()
de GNU awk
à utiliser une variable d'un tube. Dans la forme cmd | getline
résultat, cmd
est exécuté, sa sortie est ensuite acheminée vers getline
. Il retourne 1
si obtenu, 0
si EOF, -1
en cas d'échec.
Commencez par construire la commande à exécuter dans une variable de la clause BEGIN
si elle est non dépendante du contenu du fichier, par exemple. un simple date
ou un ls
.
Un exemple simple de ce qui précède serait
awk 'BEGIN {
cmd = "ls -lrth"
while ( ( cmd | getline result ) > 0 ) {
print result
}
close(cmd);
}'
Lorsque la commande à exécuter fait partie du contenu en colonnes d'un fichier, vous générez la chaîne cmd
dans le fichier principal {..}
comme ci-dessous. Par exemple. considérons un fichier dont $2
contient le nom du fichier et vous souhaitez le remplacer par le md5sum
contenu de hachage du fichier. Tu peux faire
awk '{ cmd = "md5sum "$2
while ( ( cmd | getline md5result ) > 0 ) {
$2 = md5result
}
close(cmd);
}1'
J'ai pu le faire via la méthode ci-dessous
cat ../logs/em2.log.1 |grep -i 192.168.21.15 |awk '{system(`date`); print $1}'
awk a une fonction appelée system qui vous permet d'exécuter n'importe quelle commande linux bash dans la sortie de awk.
J'utilise le pouvoir d'awk pour supprimer certains de mes conteneurs de menu fixe arrêtés. Observez attentivement comment je construis la chaîne cmd
avant de la transmettre à system
.
docker ps -a | awk '$3 ~ "/bin/clish" { cmd="docker rm "$1;system(cmd)}'
Ici, j'utilise la 3ème colonne avec le motif "/ bin/clish", puis j'extrais l'ID de conteneur dans la première colonne pour construire ma chaîne cmd
et la transmettre à system
.