IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Awk utilisation d'une variable


Sujet :

Shell et commandes GNU

  1. #1
    Candidat au Club
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Septembre 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2014
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Awk utilisation d'une variable
    Bonjour à tous,

    Je n'ai pas trouvé la réponse à ma question en lisant, en revanche je ne pense pas être une bête pour comprendre awk je galère sérieusement :/

    je dois faire une manipulation toute simple, je teste le champ 6 avec awk, si ce champs 6 est égale à la valeur de ma variable il imprime le résultat.
    Le problème c'est que je sais faire le test avec une valeur fixe mais pas avec une variable .

    Voici mon script :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    datejour=$(date +%-d);
    echo $datejour;
    #dateveille=$((datejour-1));
    #echo $dateveille;
    date_hier_jour=$(date --date '1days ago' +%-d)
    echo $date_hier_jour;
    
    
    
    #si le champs 6 est égale à ca imprimer la ligne
    awk '$6 == $((date_hier_jour)) {print $0}' out
    Toute fonctionne sauf ce test simple ^^

    Avez-vous une petite piste sur la formulation ?

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 550
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 550
    Points : 19 382
    Points
    19 382
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -v dhj="$date_hier_jour" '$6==dhj' out
    les variables ne sont pas développées entre apostrophes.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par itsme2501 Voir le message
    Avez-vous une petite piste sur la formulation ?
    Bonjour

    En fait, quand tu veux passer une valeur "externe" à un script awk, tu dois lui spécifier -v variable_interne=valeur_a_passer. A partir de là, le script awk connaitra la variable "variable_interne" et pourra s'en servir pour traiter la valeur venue de l'extèrieur.
    La valeur "valeur_a_passer" pouvant, elle, parfaitement être issue d'une variable du shell ou bien d'une commande => awk -v dhj="$(date --date '1days ago' +%-d)" '$6==dhj' out.

    Ce que tu as essayé de faire, c'est d'appeler awk en substituant, dans le code awk lui-même, la variable shell par sa valeur. Ca aurait pu fonctionner mais il aurait alors fallu ne pas utiliser les quotes simples (car elles empêchent toute substitution) pour écrire le code mais un autre outil (le backslash ou les quotes doubles). Ces outils ayant un comportement différent, il aurait alors fallu le prendre en compte dans ta syntaxe awk (faire en sorte que les caractères spéciaux du awk, comme les espaces ou le "$", ne soient alors pas interceptés par le shell.
    A titre d'exemple voici deux syntaxes qui auraient fonctionnées:
    • awk "\$6 == \"$date_hier_jour\" {print \$0}" out => protection du "$6", du "$0" et des quotes symbolisant la chaine pour ne pas qu'ils soient interceptés par le shell et qu'ils soient transmis tels quels vers awk
    • awk \$6\ ==\ \"$date_hier_jour\"\ {print\ \$0} out => idem ci-dessus mais rajout en plus de la protection des espaces pour ne pas que le shell sépare le code d'instruction et l'envoie d'un bloc à awk

    Donc comme tu vois, c'est possible mais il est quand-même plus simple d'utiliser le mécanisme permettant de passer un élément externe à awk jusque dans son code de travail et encadrer celui-ci de quotes simples pour verrouiller définitivement toute intéraction du shell...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Candidat au Club
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Septembre 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2014
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Merci pour vos réponses, je commence à mieux cerner l'utilisation de cet argument -v et la logique de awk

    En attendant j'avais réussi à le faire fonctionner avec la ligne suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '$6 == '$date_hier_jour' {print $0}' out
    Cela fonctionne ne n'était pas bien beau mais bon
    Je vais utiliser l'argument -v maintenant que j'ai compris son fonctionnement

  5. #5
    Invité
    Invité(e)
    Par défaut
    J'utilise cette solution dans certain cas.

    Si le awk est simple c'est largement suffisant.
    Mais si le awk est plus complexe, une variable via le "-v" est plus facile à suivre. Sinon on se perd avec les quotes surtout s'il n'y a pas de coloration syntaxique

  6. #6
    Candidat au Club
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Septembre 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2014
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    En tout cas, un grand merci pour vos interventions constructives et avec en prime des exemples, que demander de plus

    Maintenant tout est bon.

    Vous souhaitant une bonne journée.

  7. #7
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par itsme2501 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk '$6 == '$date_hier_jour' {print $0}' out
    Cela fonctionne ne n'était pas bien beau mais bon
    C'est pas beaucoup moins beau qu'une solution utilisant des guillemets (voir les propositions de Sve@r (que je ne critique pas!)), mais c'est la dure loi du shell
    ce qui fait qu'on a parfois des "horreurs" avec des successions de "'" et de '"'!

    C'est dû au fait que la chaîne de caractères que tu passes à awk est construite par le shell (expansion de la variable ${date_hier_jour}) et contient aussi des $ qui ne doivent pas être interprétés par le shell (car ils sont destinés à awk). L'écriture de cette chaîne contient donc 2 types de $, ceux pour le shell et ceux pour awk. Une fois qu'on a compris ça, c'est plus simple...

    [EDIT]Suite à la très juste remarque de N_BaH, je préfère corriger mon erreur plutôt que laisser traîner du code qui ne marche pas (car insuffisamment testé! )!

    Ici, ta date est un simple chiffre, mais si elle devait pouvoir contenir des espaces, il faudrait la faire tenir en 1 bloc, et, pour cela, utiliser des guillemets, à destination de awk et non du shell, ainsi que d'autres guillemets à destination du shell, comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    awk '$6 == "'$date_hier_jour'" {print $0}' out  # Oops!
    awk: non-terminated string a... at source line 1
     
    awk '$6 == "'"$date_hier_jour"'" {print $0}' out
    ...
    [/EDIT]

    Cela dit, je préfère encore la solution de N_Bah!

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    ...voir les propositions de Sve@r (que je ne critique pas!)...
    ...Cela dit, je préfère encore la solution de N_Bah!
    Attention attention, ce n'était pas une proposition mais un exemple (voire un "exercice de style pour connaisseurs") montrant que c'est toujours possible mais tout en disant que ce n'était pas à faire
    Bien entendu moi aussi j'utilise -v et si je vois un jour un appel à awk en prod écrit comme un de mes deux exemples je démonte la tronche du codeur. Il est bien évident que -v est justement fait pour transférer des valeurs (ou des variables, c'est comme on le sent) à awk et que c'est la solution présentée par N_Bah qu'il faut plébisciter !!!

    Citation Envoyé par jack-ft Voir le message
    Ici, ta date est un simple chiffre, mais si elle devait pouvoir contenir des espaces, il faudrait la faire tenir en 1 bloc, et, pour cela, utiliser des guillemets, à destination de awk...
    Bien vu
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 550
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 550
    Points : 19 382
    Points
    19 382
    Par défaut
    il faut des guillemets aussi pour le shell (et là ça devient vraiment moche) ::
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ var="bla bla"
    $ awk 'BEGIN{print ("bla" == "'"$var"'")?"ok":"KO"}'
    KO
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ $ awk 'BEGIN{print ("bla" == "'$var'")?"ok":"KO"}'
    awk: ligne de commande:1: BEGIN{print ("bla" == "bla
    awk: ligne de commande:1:                       ^ chaîne non refermée
    awk: ligne de commande:1: BEGIN{print ("bla" == "bla
    awk: ligne de commande:1:                       ^ syntax error
    ...


    on peut aussi passer des variables à awk en tant que paramètres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ awk 'END{print varAwk}' varAwk="$var" ~/monFichier
    bla bla
    petit bémol: ce type de déclaration ne fonctionne qu'à la lecture d'un fichier, donc la variable n'existera pas dans BEGIN
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  10. #10
    Expert éminent sénior Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 243
    Points : 13 458
    Points
    13 458
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    L'écriture de cette chaîne contient donc 2 types de $, ceux pour le shell et ceux pour awk.
    Tu décris le dollar utilisé comme préfixe, indicateur de variable/paramètre/champ ; mais il y a aussi le dollar comme indicateur de fin de ligne dans les expressions régulières.

    Heureusement, ça reste simple. Car avec sed, il y aurait, en quatrième possibilité, le dollar comme indicateur de dernière ligne du fichier comme adressage.

    Cette réponse vous apporte quelque chose ? Cliquez sur en bas à droite du message.

  11. #11
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 278
    Points : 12 726
    Points
    12 726
    Par défaut
    Bonjour,

    Alors une autre solution sous gawk par l'exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ unset varAwk
    $ echo bob | varAwk="toto" awk 'BEGIN{print ENVIRON["varAwk"]}'
    toto
    Cordialement.

  12. #12
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Bon, avec un mac sous la main, c'est quand même plus facile à tester…

    J'avais bien compris l'exercice de style de Sve@r et l'avais bien pris comme tel.
    En voici un autre...
    Si on veut, on peut aussi utiliser la fonction built-in de bash printf (c'est une built-in bash (bien que /usr/bin/printf existe aussi)).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ cat foo.csv   # Le fichier de données:
    a,b c,d
    e,b,f
     
    $ foo="b c"         # La variable
    $ echo "'${foo}'"
    'b c'
    On crée l'instruction destinée à awk:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ printf -v awk_code '$2 == "%s" {print $0}' "${foo}"
     
    $ echo "'${awk_code}'"     # Vérification
    '$2 == "b c" {print $0}'
     
    $ awk -F ',' "${awk_code}" foo.csv    # Test
    a,b c,d
    L'instruction avec le printf qui génère le code awk me paraît facile à écrire et à lire… tant qu'on n'a pas aussi besoin d'apostrophes…

    Si c'est le cas, on peut aussi s'amuser à faire des trucs dans ce genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    q="'"
    qq='"'
    printf -v awk_code '$2 == %s%s%s {print $0}' "$qq" "${foo}" "$qq"
    Du coup, c'est vachement plus lisible...

  13. #13
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    Du coup, c'est vachement plus lisible...
    Argh cte horreur
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [awk] Utilisation d'une variable d'environnement
    Par tiresias54 dans le forum Shell et commandes GNU
    Réponses: 7
    Dernier message: 06/08/2013, 08h26
  2. Pl/SQL utilisation d'une variable dans un select
    Par larg dans le forum PL/SQL
    Réponses: 17
    Dernier message: 30/11/2004, 17h08
  3. utilisation d'une variable globale
    Par ZZ dans le forum ASP
    Réponses: 3
    Dernier message: 03/12/2003, 19h11
  4. Utilisation d'une variable sur plusieurs unités
    Par Yamaneko dans le forum Langage
    Réponses: 2
    Dernier message: 05/06/2003, 11h23
  5. Réponses: 4
    Dernier message: 05/06/2002, 14h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo