Forum Linux.débutant Modification d'un fichier, variable avec awk

Posté par  . Licence CC By‑SA.
Étiquettes :
0
13
avr.
2020

Bonjour à tous,

Je voudrais modifier un associer une valeur à une variable avec awk en utilisant une autre variable (définie au début du programe). Voici un exemple simple qui illustre ce que je voudrais faire :

Pour le moment j’exécute la commande suivante :
Re_tau_fr=$(awk 'FNR==119{print 0.0029846/$43*sqrt($39/$17*$2/($1))}' $moyenne_actuelle)

Je voudrais pouvoir changer le coefficient multiplicateur facilement en début de fichier, c'est à dire faire quelque chose comme :
coeff="0.0029846"
Re_tau_fr=$(awk 'FNR==119{print $coeff/$43*sqrt($39/$17*$2/($1))}' $moyenne_actuelle)

En utilisant BEGIN j'y arrive mais comment combiner BEGIN et FNR ? Y'a-t-il une autre solution si la combinaison est impossible ?

Merci d'avance pour vos réponses,
Martin

  • # -v

    Posté par  . Évalué à 2.

    Salut,

    Le plus simple est d'utiliser l'option -v (awk -vcoeff="$coeff"). La variable sera assignée avant la première règle, y compris BEGIN.

    Pour répondre à la sous-question, la règle BEGIN doit être placée avant les autres.

    • [^] # Re: -v

      Posté par  . Évalué à 2.

      Il y a aussi moyen de faire un truc du genre

      Re_tau_fr=$(awk 'FNR==119{print '$coeff'/$43*sqrt($39/$17*$2/($1))}' $moyenne_actuelle)
      
      • [^] # Re: -v

        Posté par  . Évalué à 1.

        Ah oui mais attention aux injections de code.

        Et tant qu'on y est, il y a un autre moyen : quand le nom d'un fichier ressemble a une assignation de variable (var=…), l'argument est traité comme tel. Il est donc possible de modifier une même variable plusieurs fois entre deux fichiers.

        Re_tau_fr=$(awk 'FNR==119{print coeff/$43*sqrt($39/$17*$2/($1))}' coeff="$coeff1" $moyenne_actuelle coeff="$coeff2" $moyenne_actuelle)

        Mais alors la première assignation se fera après le BEGIN.

    • [^] # Re: -v

      Posté par  . Évalué à 3. Dernière modification le 16 avril 2020 à 00:00.

      en fait, BEGIN peut être n'importe où.
      je crois que c'est pour ça que ça s'appelle BEGIN. :)

      $ bash
      $ awk '{ print $0 } END{ print "fini" } BEGIN{ print "début" }' <<<"a
      b
      c"
      début
      a
      b
      c
      fini

      • [^] # Re: -v

        Posté par  . Évalué à 1. Dernière modification le 17 avril 2020 à 16:53.

        Ah oui, j'étais pourtant certain de ça. Merci de m'avoir corrigé !

        Pour ma défense, j'ai utilisé pas mal Unix v7 sur le PDP-11 du Living Computers Museum, ainsi que via émulation ces derniers temps et Awk, premier du nom, ne permet pas cette fantaisie. Je cite le manuel :

        The special patterns BEGIN and END may be used to capture control before the first input line is read and after the last. BEGIN must be the first pattern, END the last.

        Bon ben, j'espère ne pas avoir inconsciemment adopté la syntaxe K&R, qui est bien pratique quand on utilise ed et les autres outils, dans mes autres projets.

  • # Ca ne fonctionne toujours pas

    Posté par  . Évalué à 1.

    Bonjour,

    Merci pour vos réponses. Cependant je ne parviens pas à les faire fonctionner, le programme se bloque sur cette ligne et n'affiche rien. Sur un exemple vraiment simple :

    val=99
    awk -v lambdafr="$val" '{print lambda_fr }'

    et

    awk '{print lambda_fr}' lambda_fr="$val"

    Ne donnent rien.

    Quant à la combinaison de BEGIN et FNR, je ne vois pas trop comment les imbriquer.
    awk 'BEGIN{FNR==119{print $coeff/$43*sqrt($39/$17*$2/($1))}}' $moyenne_actuelle

    Ne fonctionne pas non plus.

    Ai-je un autre problème ?
    Merci encore !

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.