2009-12-08 4 views
3

J'ai besoin d'exécuter une commande par ligne de certains fichiers. Par exemple:awk save commande ouput to variable

file1.txt 100 4 
file2.txt 19 8 

donc mon script awk besoin d'exécuter quelque chose comme

command $1 $2 $3 

et enregistrer la sortie de command $1 $2 $3, donc system() ne fonctionnera pas et ni volonté getline. (Je ne peux pas canaliser la sortie si je fais quelque chose comme ceci.)

La restriction à ce problème est d'utiliser seulement awk. (j'avais déjà une solution avec bashscriot + awk ... mais je veux seulement awk ... juste en savoir plus à ce sujet)

Répondre

2

Qu'est-ce qui ne va pas avec l'utilisation getline?

 
$ ./test.awk test.txt 
# ls -F | grep test 
test.awk* 
test.txt 

# cat test.txt | nl 
    1 ls -F | grep test 
    2 cat test.txt | nl 
    3 cat test.awk 

# cat test.awk 
#!/usr/bin/awk -f 
{ 
     cmd[NR] = $0 
     while ($0 | getline line) output[NR] = output[NR] line RS 
} 
END { 
     for (i in cmd) print "# " cmd[i] ORS output[i] 
} 
+0

ce script est bash. quand j'utilise getline je ne peux pas canaliser la commande, par exemple cat fichier | paramètres de processus, je reçois seulement le fichier chat. Je le fais pour plus de façons propres de faire cette tâche ... – llazzaro

+0

Quel 'awk'? Cela fonctionne ici, avec GNU Awk 3.1.7. – ephemient

+0

les 10 dernières lignes ont répondu à ma question – llazzaro

0

fonction system() awk passe la chaîne à/bin/sh, de sorte que vous pouvez utiliser redirect les opérateurs, comme "> file.out" si vous voulez.

awk '{system("command " $1 " " $2 " " $3 ">" $1 ".out");}' 

Editer: ok, par sauvegarder, vous voulez dire dans une variable awk. éphémient est sur la bonne voie, alors. C'est ce que fait getline d'awk, comme les backticks ou $ (cmd) dans shell/perl. En fait, google pour backticks awk trouvé ceci: http://www.omnigroup.com/mailman/archive/macosx-admin/2006-May/054665.html

Vous dites que vous ne pouvez pas utiliser getline parce que vous ne pouviez pas canaliser. Mais vous pouvez contourner cela avec des astuces de tee et de descripteur de fichier. Cela fonctionne si/bin/sh est bash:

{ "set +o posix; command " $1 " " $2 " " $3 " | tee >(grep foo)" | getline var; print toupper(var); } # bash-only, and broken. 

set +o posix est nécessaire parce que awk fonctionne bash comme sh, ce qui en fait passer en mode posix après lecture de ses fichiers de démarrage. Hmm, je n'ai pas de chance pour que ça marche, et ça demande de l'argent de toute façon.

Ok, cela fonctionne:


    $ touch foo bar 
    $ echo "foo bar" | 
     awk '{ "{ ls " $1 " " $2 " " $3 " | tee /dev/fd/10 | grep foo > /dev/tty; } 10>&1" | getline var; print toupper(var); }' 
    foo 
    BAR 
+0

ma solution actuelle fait cela, mais je ne peux pas envoyer la sortie de la commande à une variable – llazzaro

+0

Vous pouvez slurp la sortie en retour avec une boucle 'readline [...] <$ 1" .out "' suivante. N'oubliez pas de nettoyer après vous-même ... – ephemient

+0

J'ai utilisé une redirection de descripteur de fichier pour canaliser et getline en même temps. Cela fait-il ce dont vous avez besoin? –

Questions connexes