Posez votre question Signaler

[Awk] appel variable système dans script awk

Daakon - Dernière réponse le 28 sept. 2009 à 10:41
Bonjour,
Je suis un débutant Unix et me casse les dents sur une commande que je souhaite intégrer à un script .awk.
J'ai dans mon système une variable système $PATTERN qui contient un chemin prédéfini.
echo $PATTERN
directement en ligne de commande linux ramène la valeur voulue.
Je souhaite intégrer à mon script awk une ligne de commande où j'apelle ce $PATTERN.
J'ai donc construit le code suivant qui ne fonctionne pas:
CommandLine="awk -F \"=\" '$1==out {print  $2 }' "$PATTERN"/chemin.ini| head -n 1"

Il semble que le $PATTERN ne soit pas trouvé et qu'il cherche donc le chemin.ini dans le repertoire d'execution du script awk.
Alors que si je reprend le même code directement en ligne de commande, le $PATTERN va être pris en compte, le chemin.ini va être trouvé et le reste de la commande awk va se faire normalement.
awk -F"=" '$1=="out" {print $2}' "$PATTERN"/chemin.ini

Je ne comprend pas pourquoi directement en ligne de commande, la variable est correctement trouvée alors qu'une fois dans un script, cette variable ne semble plus exister.
J'ai trouvé dans le forum la suggestion du -v
J'ai donc essayé la ligne suivante :
CommandLine="awk -v PATTERN=$PATTERN  -F \"=\" '$1==out {print = $2 }' "PATTERN"/chemin.ini| head -n 1"

Qui me renvoie l'erreur :
cannot open file `/chemin.ini' for reading (No such file or directory)

J'ai également essayé d'affecter $PATTERN dans une variable "TOTO" appelée par la suite dans la CommandLine
TOTO= $PATTERN"/chemin.ini"
awk -F"=" '$1=="out" {print $2}' "TOTO"

Le résultat est le même. $PATTERN n'est pas lu et TOTO reste vide.
Bref, je tatonne, sans trouver de solution.
Vu que je débute peut être s'agit t'il d'une bête erreur de syntaxe.
Merci d'avance pour votre aide.
Lire la suite 

[Awk] appel variable système dans script awk »

Suggestions
11 réponses
Réponse
+0
moins plus
Salut,

Ta syntaxe pour ta variable "CommandLine" n'est pas bonne :
CommandLine=$(awk -F \"=\" '$1==out {print  $2 }' "$PATTERN"/chemin.ini| head -n 1)
Devrait aller mieux ;-))
Daakon - 2 avril 2009 à 09:19
Merci pour ta réponse.

Ce qui me déroute dans ce que tu dis, c'est que cette syntaxe fonctionne parfaitement avec d'autres fonctions du script.

A priori ce n'est pas ca qui expliquerait non plus pourquoi je n'arrive pas à affecter ma variable $PATTERN dans une variable awk.

Par acquis de conscience j'ai essayé avec ta syntaxe et elle me ramène l'erreur suivante :

awk: adeo_desadv_bl_tst.awk:574:         CommandLine=$(awk -F \"=\" '$1==out {print = $2 }'
 "$PATTERN"/chemin.ini| head -n 1)
awk: adeo_desadv_bl_tst.awk:574:                          ^ backslash not last character on line


Le problème ne se présente que lorsque je souhaite intégrer une variable d'environnement dans le script awk.
Ajouter un commentaire
Réponse
+0
moins plus
Oups ;-(

J'avais pas fait attention à ces anti-slashs en trop :
CommandLine=$(awk -F "=" '$1==out {print  $2 }' "$PATTERN"/chemin.ini| head -n 1)
Daakon - 2 avril 2009 à 09:47
Ca le fait couiner pour autre chose maintenant.

awk: desadv_bl_tst.awk:574:         CommandLine=$(awk -F "=" '$1==out {print = $2 }' "$PATTERN"/chemin.ini| head -n 1)
awk: desadv_bl_tst.awk:574:                                  ^ invalid char ''' in expression


J'ai tenté avec en retirant les ' sans plus de succès.

Comme je te dis la syntaxe semble fonctionner parfaitement sur le reste de mon script, sauf dans le cas où j'essaye de passer ma variable système dedans.

Peut être existe il un moyen de "protéger" cette variable ou de l'enregistrer dans une variable intermédiaire.
Ajouter un commentaire
Réponse
+0
moins plus
Essaye en enlevant l'espace :
awk -F"="
;-\
Daakon - 2 avril 2009 à 10:18
Strictement pareil, hélas.
Ajouter un commentaire
Réponse
+0
moins plus
Ben je ne comprends pas ;-\

J'ai pris une variable système sur mon PC ($MAIL) et voilà ce que ça donne :
jp@MDK:~/tmpfs ssh$ echo $MAIL
/var/spool/mail/jp

jp@MDK:~/tmpfs ssh$ awk -F":" '$1 ~ /Status/ { print $2 }' $MAIL | head -1
 RO

jp@MDK:~/tmpfs ssh$ var=$(awk -F":" '$1 ~ /Status/ { print $2 }' $MAIL | head -1)

jp@MDK:~/tmpfs ssh$ echo $var
RO

jp@MDK:~/tmpfs ssh$
;-))
Daakon - 2 avril 2009 à 10:48
Je suis tout a fait d'accord avec toi, chez moi aussi ca fonctionne dans ces conditions.

Mais dès que j'essaye de passer tout ca dans un fichier script .awk, ca se met à ne plus fonctionner et ca ne me parait pas être un problème de syntaxe du commandline puisque j'arrive à l'utiliser tel que je l'écrit pour tout le reste de mon script.

Bizarre autant qu'étrange, non ?
jipicy- 2 avril 2009 à 10:52
dans un fichier script .awk
C'est à dire ?
C'est awk qui appelle ce fichier ou ton shell ?
Que contient exactement ce fichier ?
Daakon - 2 avril 2009 à 11:30
C'est à dire que j'ai un fichier desadv_bl.awk qui contient toute une série de commandes qui traite de trucs assez complexes. (un fichier que je n'ai pas écrit moi même pour ne rien te cacher).

ce script est apellé avec une commande passée directement en ligne :

awk  -f desadv_bl.awk < test.tx


Tout fonctionne nickel sans que j'y touche, la seule chose que je veux faire est d'ajouter une fonction qui va lire une information du fichier chemin.ini et l'affecter à une variable que je souhaite utiliser pour la suite.

Code de ma fonction :

function trouveChemin (pattern){
#Remarque : je passe à la fonction pattern=out, ce qui explique ma mise en commentaire plus bas
        
        print "pattern : " pattern
# Le print marche nickel, le bon paramètre est passé, pas de problèmes.
	sauvegardeLigne=$0
	$0=""

        PATTERN2= "$PATTERN"/chemin.ini        
        print "PATTERN2 :" PATTERN2       
# Il s'agit du relicat d'un de mes tests. J'avais essayé d'affecter la valeur de "$PATTERN"/chemin.ini  dans une
#variable que j'aurai pu apeller plus bas dans le commandline. Helas le $PATTERN ne s'affecte pas dans la 
#variable, le print ne m'affiche que "/chemin.ini"

#       CommandLine="awk -F \"=\" '$1=="pattern" {print $2}' $PATTERN/chemin.ini| head -n 1" 
         CommandLine="awk -F\"=\" '$1==out {print = $2 }' "$PATTERN"/chemin.ini| head -n 1)
#Les deux lignes précédentes donnent le même résultat, que j'utilise l'une ou l'autre.

         CommandLine | getline
         toto=$2
         print "toto : " toto
         close(CommandLine)

         $0=sauvegardeLigne
         return toto
	}


Je tiens à préciser que faute de comprendre ce que je faisais, j'ai repris la syntaxe exacte d'une autre fonction présente dans ce script et qui fonctionne :

function trouveCommentaire(numero){
	sauvegardeLigne=$0
	$0=""
	CommandLine="awk -F\";\" '$1==" numero " {print $2}' " FICHIER_COMMENTAIRE " | head -n 1"
#Avec FICHIER_COMMENTAIRE étant une variable que j'ai définie plus haut qui pointe vers 
#le fichier que je souhaite lire pour trouver mon commentaire.
	CommandLine | getline
	commentaire=$0
	close(CommandLine)
	
	$0=sauvegardeLigne
	return commentaire
}


Le retour se fait nickel dans ces conditions et j'arrive à récupérer mon commentaire.

Vraiment, la seule différence que je detecte c'est que je n'arrive pas à apeller ma variable $Pattern dans ce script.
Ajouter un commentaire
Réponse
+0
moins plus
C'est lors de l'appel du script awk global qu'il faut passer ton $PATTERN à awk avec -v
Et ensuite travailler uniquement avec les variables awk dans ton script awk et ne pas mixer les 2
Ne pas confondre les variables de ton shell et celles que awk connait.

awk -v PATTERN=$PATTERN -f desadv_bl.awk < test.tx

et donc il te faut modifier le contenu de ton script awk en conséquence

CommandLine="awk -F\"=\" '$1==out {print = $2 }' "PATTERN"/chemin.ini| head -n 1"
Ajouter un commentaire
Ce document intitulé « [Awk] appel variable système dans script awk » issu de CommentCaMarche (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Dossier à la une
Passage au tout numérique : quel coût pour les particuliers ?