web-dev-qa-db-fra.com

Appeler un programme exécutable en utilisant awk

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?

39
user2030431

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")
43
Caleb

Il y a plusieurs façons.

  1. awk a une fonction system() qui exécutera une commande shell:

    system("cmd")

  2. Vous pouvez imprimer sur un tuyau:

    print "blah" | "cmd"

  3. Vous pouvez avoir des commandes de construction awk et diriger toute la sortie vers le shell:

    awk 'some script' | sh

23
Barmar

Quelque chose d'aussi simple que cela fonctionnera

awk 'BEGIN{system("echo hello")}'

et

awk 'BEGIN { system("date"); close("date")}'

5
Mirage
#!/usr/bin/awk -f

BEGIN {
    command = "ls -lh"

    command |getline
}

Lance "ls -lh" dans un script awk

3
Graham

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).

3
Felix

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'
2
Inian

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.

0
Mansur Ali

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.

0
typelogic