Forum Programmation.shell Commande sed changer un mot par la valeur d'une variable

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
0
15
fév.
2018

Bonjour à tous,

Je suis désespérément à la recherche d'un exemple de commande SED qui me permettrait de changer un mot (ici LOGJOUR) dans un fichier (fichier.txt), par la valeur d'une variable (logjour) déclarée dans mon script .

La variable récupère sa valeur dans un autre fichier nommé AA.022018

logjour= $(grep $(date +%Y-%m-%d) AA.$(date +%m%Y))

sed -e "s/LOGJOUR/$logjour/g" fichier.txt

Sachant que le echo de la variable me renvoi les bonnes infos, ça se passe vraiment au niveau de SED que je ne sais pas manipuler.

Si quelqu'un peut me guider, j'ai essayé des tonnes de combinaisons et je m'y perd.

Merci

  • # ignorer

    Posté par  . Évalué à 1. Dernière modification le 15 février 2018 à 18:38.

    Poste supprimé.

    Mal lue ta description. dsl.

  • # Format de ta date ?

    Posté par  . Évalué à 2.

    Peux tu faire un echo "$logjour" pour avoir une idée précise du format ? (je ne comprends ta ligne logjour=…)

  • # un truc du gene ...

    Posté par  . Évalué à 2. Dernière modification le 15 février 2018 à 19:02.

    sed -e "s/LOGJOUR/"$logjour"/g" fichier.txt

    • [^] # Re: un truc du gene ...

      Posté par  . Évalué à 2.

      Si ça marche pas, essaie en remplaçant les doubles quotes par des simples quotes.

      • [^] # Re: un truc du gene ...

        Posté par  . Évalué à 3. Dernière modification le 16 février 2018 à 01:45.

        S’il met des guillemets simples autour de son expression sed il devrait se retrouver avec $logjour littéralement écrit dans son fichier.

        stef@medusa:~$ h=op
        + h=op
        stef@medusa:~$ echo "plop" |sed -e 's/plop/$h/'
        + echo plop
        + sed -e 's/plop/$h/'
        $h
        stef@medusa:~$ echo "plop" |sed -e "s/plop/$h/"
        + sed -e s/plop/op/
        + echo plop
        op
        

        EDIT: Arf, j’avais pas vu que tu utilisais deux fois les quotes…

        stef@medusa:~$ echo "plop" |sed -e "s/plop/'"$h"'/"
        + echo plop
        + sed -e 's/plop/'\''op'\''/'
        'op'
        

        C’est bon, j’ai mal au crâne :)

        • [^] # Re: un truc du gene ...

          Posté par  . Évalué à 4.

          $ var=titi
          $ echo "abc toto tata" | sed 's/toto/'$var'/g'
          abc titi tata
          $ echo "abc toto tata" | sed -e 's/toto/'$var'/g'
          abc titi tata
          $ echo "abc toto tata" | sed -e "s/toto/"$var"/g"
          abc titi tata
          
        • [^] # Re: un truc du gene ...

          Posté par  . Évalué à 3.

          EDIT: Arf, j’avais pas vu que tu utilisais deux fois les quotes…

          J'ai pas précisé dans a réponse parce que c'est pas simple de faire long sur un écran de telephone portable …
          J'ai essayé chez moi et j'ai copié/collé l'exemple par ailleurs.

  • # Hello

    Posté par  . Évalué à 3.

    $logjour va être remplacé par son contenu, avant d’être passée en argument à sed, car tu utilises des doubles quotes. Comme dit Kangs, il faudrait savoir ce que contient ta variable, car c’est là qu’il y a un caractère qui se retrouve interprété par sed (et pas simplement considéré comme un bout de la chaîne de remplacement…) qui fait que ça ne produit pas le résultat escompté (que tu ne nous indiques pas non plus… Message d’erreur ? Sortie nulle ?).

    Utilise la syntaxe qui va bien quand tu veux copier/coller du code ici. Parce que là c’est vraiment chiant, on y comprend que dalle…

    j'ai essayé des tonnes de combinaisons et je m'y perd.

    L’« échappement des caractères », quand on commence à en combiner plusieurs (ici sed+shell), ça peut vite donner mal au crâne c’est clair :)

    Tu peux mettre un set -x au début de ton script, comme ça lorsqu’il s’exécute il affiche toutes les commandes intermédiaires, tu verras ce que devient ton /$logjour/ ça te permettra de voir où est l’erreur.

  • # contenu de $logjour ?

    Posté par  . Évalué à 3.

    Que contient la variable $logjour? Parce que si comme son nom le laisse supposer c'est le nom d'un fichier, et que ce nom comprend le chemin complet (donc les slashes), il va falloir choisir un autre séparateur pour la commande "s" de sed. Par exemple

    sed -e "s%LOGJOUR%${logjour}%g" fichier.txt
  • # Tout simplement

    Posté par  (site web personnel) . Évalué à 0.

    :$: a='uvwy/z' ; sed -e 's/bc/'"${a//\//\\/}"'/g' <<< "abcdefgh/ijk"
    auvwy/zdefgh/ijk
    • [^] # Re: Tout simplement

      Posté par  . Évalué à 0.

      je vois pas pourquoi c'est moinsé, alors que ça répond au problème soulevé…

      • [^] # Re: Tout simplement

        Posté par  . Évalué à 1.

        Parce que c'est pas très élégant et lisible, alors que la réponse du dessus avec l'utilisation d'un autre séparateur est bien plus lisible et digeste :)

        • [^] # Re: Tout simplement

          Posté par  . Évalué à 1.

          Oui et non : c'est effectivement indigeste, mais si par malheur il t'arrivait d'avoir un % dans ta log, tu auras de nouveau le problème, et il te faudra alors chercher un nouveau séparateur, etc.

  • # retour de mon echo $logjour

    Posté par  . Évalué à 1.

    C'est en fait des ligne de log de backuppc…

    2018-02-15 TEST 2018-02-15 16:00:01 incr backup started back to 2018-02-14 15:03:12 (backup #3) for share ebtek$ 2018-02-15 16:13:37 Output from DumpPostUserCmd: /var/lib/backuppc/logmail.sh: 4: /var/lib/backuppc/logmail.sh: 2018-02-15: not found 2018-02-15 16:13:37 Output from DumpPostUserCmd: repertoire de backup 2018-02-15 16:13:37 Output from DumpPostUserCmd: /var/lib/backuppc/pc/192.168.20.6 2018-02-15 16:13:37 Output from DumpPostUserCmd: Journal 2018-02-15 16:13:37 Output from DumpPostUserCmd: 2018-02-15 16:13:38 incr backup 4 complete, 0 files, 0 bytes, 18 xferErrs (0 bad files, 0 bad shares, 18 other)

    J'ai modifier ma commande comme suit et voici ce qu'il me renvoi

    sed -e "s/LOGJOUR/"$logjour"}/g" $maildir/mail.html

    et comme ça aussi au cas où…

    sed -e 's/LOGJOUR/'$logjour'}/g' $maildir/mail.html

    sortie :

    sed: -e expression n°1, caractère 20: commande `s' inachevée

    • [^] # Re: retour de mon echo $logjour

      Posté par  . Évalué à 1.

      ton souci est que logjour contient des /, et tu utilises / comme séparateur dans le s///.

      tu peux tricher en replaçant les / par des @ dans la commande sed, mais c'est en supposant que tu n'auras pas de @ dans tes logs… (tu peux faire de même avec plus ou moins n'importe quel caractère…)

      % echo $mylog
      2018-02-15 TEST 2018-02-15 16:00:01 incr backup started back to 2018-02-14 15:03:12 (backup #3) for share ebtek$ 2018-02-15 16:13:37 Output from DumpPostUserCmd: /var/lib/backuppc/logmail.sh: 4: /var/lib/backuppc/logmail.sh: 2018-02-15: not found 2018-02-15 16:13:37 Output from DumpPostUserCmd: repertoire de backup 2018-02-15 16:13:37 Output from DumpPostUserCmd: /var/lib/backuppc/pc/192.168.20.6 2018-02-15 16:13:37 Output from DumpPostUserCmd: Journal 2018-02-15 16:13:37 Output from DumpPostUserCmd: 2018-02-15 16:13:38 incr backup 4 complete, 0 files, 0 bytes, 18 xferErrs (0 bad files, 0 bad shares, 18 other)
      % cat mail.html
      pouet
      LOGJOUR
      pouetpouet
      % sed -e "s@LOGJOUR@$mylog@g" mail.html
      pouet
      2018-02-15 TEST 2018-02-15 16:00:01 incr backup started back to 2018-02-14 15:03:12 (backup #3) for share ebtek$ 2018-02-15 16:13:37 Output from DumpPostUserCmd: /var/lib/backuppc/logmail.sh: 4: /var/lib/backuppc/logmail.sh: 2018-02-15: not found 2018-02-15 16:13:37 Output from DumpPostUserCmd: repertoire de backup 2018-02-15 16:13:37 Output from DumpPostUserCmd: /var/lib/backuppc/pc/192.168.20.6 2018-02-15 16:13:37 Output from DumpPostUserCmd: Journal 2018-02-15 16:13:37 Output from DumpPostUserCmd: 2018-02-15 16:13:38 incr backup 4 complete, 0 files, 0 bytes, 18 xferErrs (0 bad files, 0 bad shares, 18 other)
      pouetpouet

  • # Résolu grâce à vous merci

    Posté par  . Évalué à 1. Dernière modification le 19 février 2018 à 12:57.

    La commande est donc celle-ci. Pour que la ligne de texte (valeur de $logjour) soit considérée comme tel il faut deux double-quotes.

    cat mail.html | sed -e "s%LOGJOUR%""$logjour""%g" > $maildir/mail1.html

    Merci beaucoup pour l'aide.

    • [^] # Re: Résolu grâce à vous merci

      Posté par  . Évalué à 2.

      Pour le plaisir d'utiliser ed :-)

      ed --quiet --loose-exit-status mail.html <<EOD
      %s,LOGJOUR,$logjour,g
      wq $maildir/mail1.html
      EOD
      
  • # Je relance le sujet

    Posté par  . Évalué à 1.

    Pas mieux.

    Je ne sais pas comment,mais ça a fonctionné puis plus rien.

    C'est à n'y rien comprendre.

    La commande ci-dessus me remplace ma chaîne LOGJOUR par la chaîne ""$logjour"" et non pas la valeur de $logjour.

    Si qqun à une idée de génie je suis preneur…

    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.