Partage
  • Partager sur Facebook
  • Partager sur Twitter

Script shell - substitution dans plusieurs fichier

    8 février 2023 à 1:12:27

    Bonjour,

    Afin de me faciliter la tâche lorsque je génère un projet à partir d'un template,
    j'ai écrit un script qui recherche dans les fichiers toutes les occurrences de gimp-plugin-template et les remplace par la valeur du paramètre -n entré en argument du script:

    #!/bin/bash
    # Set variables
    pluginName=""
    ############################################################
    # Help                                                     #
    ############################################################
    HelpMe()
    {
    	# Display Help
    	echo "Add description of the script functions here."
    	echo
    	echo "Syntax: create-plug-in [-h] -n name"
    	echo "options:"
    	echo "h     Print this Help."
    	echo "n     name of the plug-in."
    	echo
    }
    
    ############################################################
    # Run                                                      #
    ############################################################
    Run()
    {
    	mkdir $pluginName
    	cp -a Template/. $pluginName
    	cd $pluginName
    
    	source="'gimp-plugin-template'"
    	target="'s/gimp-plugin-template/$pluginName/g'"
    	grep -RiIl $source | xargs sed -i $target
    	source=${source//-/_}
    	target=${target//-/_}
    	first=${first/Suzy/$second}
    	grep -RiIl $source | xargs sed -i $target
    	cd ..
    	echo "Plugin: "$pluginName" created."
    }
    
    ############################################################
    # Main program                                             #
    ############################################################
    ############################################################
    # Process the input options. Add options as needed.        #
    ############################################################
    # Get the options
    while getopts ":hn:" option; do
    	case $option in
    	h) # display Help
    		HelpMe
    		exit;;
    	n) # run commands
    		pluginName=$OPTARG
    		Run
    		exit;;
    	\?) # Invalid option
    		echo "Error: Invalid option"
    		exit;;
       esac
    done
    

    Malheureusement, lorsque j'exécute, j'obtiens ceci:

    sed: -e expression #1, char 1: unknown command: `''
    sed: -e expression #1, char 1: unknown command: `''
    Plugin: Sample created.
    
    Le dossier est bien crée ainsi que les fichiers, mais aucune substitution n'a été faite.

    -
    Edité par Deedolith 8 février 2023 à 18:50:05

    • Partager sur Facebook
    • Partager sur Twitter
      8 février 2023 à 4:29:44

      Pourquoi mets-tu des ' dans les chaînes ? En bash l'utilisation des variables doit se faire dans des doubles quotes pour éviter que l’interpréteur fasse une expansion du contenu, mais il ne faut pas ajouter des quotes dans les chaînes.

      	source="gimp-plugin-template"
      	target="s/gimp-plugin-template/$pluginName/g"
      	grep -RiIl "$source" | xargs -d'\n' sed -i "$target" # ajout de -d'\n' pour éviter des problèmes avec des chemins contenant des espaces
      	source=${source//-/_}
      	target=${target//-/_}
      	grep -RiIl "$source" | xargs -d'\n' sed -i "$target"
      • Partager sur Facebook
      • Partager sur Twitter
        8 février 2023 à 8:44:53

        D'une part, les commandes que j'avait en exemple fonctionnaient avec des simples cottes (hors script), donc je les ai reprises.

        D'autre part, je vient de faire le test avec la syntaxe que tu proposes:

        sed: no input files
        sed: no input files
        
        • Partager sur Facebook
        • Partager sur Twitter
          8 février 2023 à 10:31:51

          jo_link_noir a écrit:

          # ajout de -d'\n' pour éviter des problèmes avec des chemins contenant des espaces

          sachant qu'un nom de fichier, sur Linux, peut contenir n'importe quel caractère à part NULL, je proposerais plutôt 

          grep -RilZ "$motif" | xargs --no-run-if-empty --null sed -i 's/'"$motif"'/'"$substitution"'/g'

          je me demande si, en bash, on ne pourrait pas se passer de grep|xargs, en passant par globstar (et nullglob, bien sûr :D).

          edit : « script shell » ? tu n'as pas plus précis à dire pour permettre à ceux qui auront le même souci de trouver ta discussion, et probablement une solution ?!

          -
          Edité par dantonq 8 février 2023 à 23:10:50

          • Partager sur Facebook
          • Partager sur Twitter

          Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

            8 février 2023 à 18:58:35

            @dantonq: Dsl pour le titre, j'ai mis à jour.

            Malheureusement, ta solution ne produit pas de meilleurs résultats:

            sed: -e expression #1, char 30: unknown option to `s'

            Il doit y avoir des subtilités qui m'échappent.

            Pour infos, ma commande de base, qui avait fonctionné en ligne de commande, était:

            grep -RiIl 'gimp-plugin-template' | xargs sed -i 's/gimp-plugin-template/sample/g'



            Je précise également que je ne suis pas sur un vrai linux, mais environnement MSYS2.

            • Partager sur Facebook
            • Partager sur Twitter
              8 février 2023 à 19:52:31

              tu remarqueras que le message d'erreur change. :)

              il faudrait nous indiquer quel paramètre tu passes au script.

              PS: puisque quelque soit l'option passée au script, il sort, l'exit pourrait être mis en dehors de la boucle while.

              -
              Edité par dantonq 8 février 2023 à 19:52:57

              • Partager sur Facebook
              • Partager sur Twitter

              Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                8 février 2023 à 23:04:13

                Sauf que le problème ne se situe pas dans la fonction principale qui prend en charge les paramètres, mais dans la fonction Run().
                Mais si tu y tiens, voici ma ligne de commande:

                ./create-plugin.sh -n sample

                Avec:
                create-plugin.sh: Le nom du script
                sample: un nom quelconque.

                Le but est de copier le contenu du dossier template dans un noouveau dossier nommé d'après le nom suivant le paramètre -n (sample dans mon cas), et substituer ce nom à gimp-plugin-template et gimp_plugin_template dans tous les fichiers du dossier et sous dossiers nouvellement créés.

                • Partager sur Facebook
                • Partager sur Twitter
                  8 février 2023 à 23:19:34

                  ce paramètre est utilisé dans Run(), c'est pour ça que je demande.

                  heu... tu n'utilises pas $motif et $substitution telles quelles n'est-ce pas ?
                  ce sont des noms évocateurs de ce que les variables doivent contenir, mais elles n'ont pas été définies ! et forcément, sed ne comprend pas quoi faire.

                  PS : $second n'est pas défini, donc Suzy sera remplacé par rien; peu importe, tu n'utilises pas first. :)

                  • Partager sur Facebook
                  • Partager sur Twitter

                  Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                    8 février 2023 à 23:52:29

                    Ca a fini par fonctionner (je ne sais pas comment).

                    Run()
                    {
                    	mkdir $pluginName
                    	cp -a Template/. $pluginName
                    	cd $pluginName
                    
                    	motif="gimp-plugin-template"
                    	substitution=$pluginName
                    		#remplace les underscore eventuels par des tirets
                    	substitution=${substitution//_/-}
                    	grep -RilZ "$motif" | xargs --no-run-if-empty --null sed -i 's/'"$motif"'/'"$substitution"'/g'
                    		#remplace les tirets par des underscore
                    	motif=${motif//-/_}
                    	substitution=${substitution//-/_}
                    	grep -RilZ "$motif" | xargs --no-run-if-empty --null sed -i 's/'"$motif"'/'"$substitution"'/g'
                    	cd ..
                    	echo "Plugin: "$pluginName" created."
                    }
                    • Partager sur Facebook
                    • Partager sur Twitter
                      8 février 2023 à 23:57:41

                      pourquoi est-ce que tu passes de _ à - puis de - à _ ? surtout, pourquoi les deux manipulations ? une seule devrait suffire, non ?
                      • Partager sur Facebook
                      • Partager sur Twitter

                      Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                        9 février 2023 à 0:06:39

                        Il y a des sources écrits en différent langages derrière, certains supportent les tiret, d'autre les underscore.
                        (ce ne sont que des vulgaires détails d'implémentation).
                        • Partager sur Facebook
                        • Partager sur Twitter
                          9 février 2023 à 0:28:28

                          prenons deux "mots" : foo-bar_baz et ga_bu-zo

                          les deux substitutions sont accomplies, et le résultat sera le même foo_bar_baz et ga_bu_zo : il n'y a que des soulignements

                          une seule substitution suffirait : remplacer les tirets par des soulignements. `comprends pas. :euh:

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                            9 février 2023 à 0:54:17

                            Ben non (je viens de tester).
                            Avec foo-bar_baz:
                            Il substitue foo-bar-baz à gimp-plugins-template
                            Il substitue foo_bar_baz à gimp_plugins_template

                            • Partager sur Facebook
                            • Partager sur Twitter
                              9 février 2023 à 1:36:45

                              c'est de ça que je parle :

                              $ substitution='foo_bar-baz'
                              $ substitution=${substitution//_/-} #pourquoi changer les soulignements ?
                              $ substitution=${substitution//-/_}
                              $ echo $substitution 
                              foo_bar_baz
                              $ 
                              

                              remettons :

                              $ substitution='foo_bar-baz'
                              $ substitution=${substitution//-/_}
                              $ echo $substitution 
                              foo_bar_baz
                              $ 
                              une seule substitution fait le même travail.

                              -
                              Edité par dantonq 9 février 2023 à 1:37:19

                              • Partager sur Facebook
                              • Partager sur Twitter

                              Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                                9 février 2023 à 9:05:20

                                J'ai 2 chaines à remplacer, qui n'ont pas tout à fait la même forme, je m'assure que les argument en entrée ont la bonne forme.

                                PS: Je ne voit pas pourquoi tu t'obstines, le script fait maintenant ce que je souhaite.

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  9 février 2023 à 11:14:21

                                  parce que je trouve bizarre de faire deux manipulations quand une seule suffit.
                                  Run()
                                  {
                                      mkdir "$pluginName" #toujours des guillemets autour des Développement de paramètres
                                      cp -a /cheminAbsolu/Template/. "$pluginName" #indiquer les chemins absolus, pour éviter cd
                                      motif="gimp[-_]plugin[-_]template" #motif avec - OU _
                                      substitution=$pluginName #ne sert pas à grand chose, mais bon
                                      #ligne de commandes sur plusieurs lignes pour la lisibilité
                                      grep -RilZ "$motif" "$pluginName"/ \
                                          | xargs -r -0 \
                                               sed -i '/'"$motif"'/{
                                                  s/-/_/g;
                                                  s/'"$motif"'/'"$substitution"'/g}'
                                      printf 'Plugin: %s created.' "$pluginName" #en espérant que tout se soit bien passé
                                  }
                                  
                                  ça devrait marcher aussi bien, en étant plus simple (en respectant le KISS principle).

                                  -
                                  Edité par dantonq 9 février 2023 à 16:51:52

                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                                    9 février 2023 à 18:18:11

                                    Il faudra que tu m'explique comment tu réalise 2 substitutions différentes avec une seule instruction ...

                                    Je suis loin d'être ne serait-ce que novice en scripts shell, donc je fait simple et naïf.

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      9 février 2023 à 20:01:29

                                      je t'ai montré qu'une seule substitution est nécessaire :
                                      soulignements -> tirets + tirets -> soulignements = tirets -> soulignements
                                      je ne comprends pas que tu ne le voies pas.

                                      motif est maintenant « mot [- OU _] mot [- OU _] mot »

                                      NB: j'ai peut-être fait une erreur, il faudrait inverser :

                                      sed -i '/'"$motif"'/{
                                         s/'"$motif"'/'"$substitution"'/g;
                                         s/-/_/g;
                                      }'

                                      sans fichier modèle, rédiger une commande sed est un peu abstrait. :)

                                      -
                                      Edité par dantonq 9 février 2023 à 20:02:01

                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                                        9 février 2023 à 23:50:11

                                        dantonq a écrit:

                                        je t'ai montré qu'une seule substitution est nécessaire

                                        Désolé, il m'en faut 2, je doit substituer 2 chaînes différentes.
                                        De plus, j'ai testé tes dernières solutions, elles sont KO.

                                        Donc tu me permettra de rester sur mes positions.

                                        -
                                        Edité par Deedolith 9 février 2023 à 23:51:11

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          10 février 2023 à 1:20:56

                                          je te l'ai montré, tu n'es pas capable de l'admettre.

                                          allez, j'essaie encore une fois avec des billes de couleurs :

                                          quand dans un sac de billes, tu remplaces
                                          toutes les rouges par des bleues (alors, il n'y a plus que des bleues)
                                          puis
                                          toutes les bleues par des rouges (alors, il n'y a plus que des rouges)

                                          c'est comme si tu avais remplacé directement, uniquement et simplement, toutes les billes bleues par des billes rouges.

                                          après tes deux opérations, comme après la seule mienne, à la fin, il n'y a plus que des billes rouges dans le sac !

                                          -
                                          Edité par dantonq 10 février 2023 à 1:52:50

                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                                            10 février 2023 à 3:15:22

                                            De ce que je comprends, il y a bien 2 types de remplacement. Avec pluginName=a-plugin:

                                            • les gimp-plugin-template seront remplacés par a-plugin
                                            • les gimp_plugin_template seront remplacés par a_plugin

                                            Si on veut le faire en une seule commande, le code devrait plutôt ressembler à

                                            motif='gimp-plugin-template'
                                            substitution=${pluginName//_/-}
                                            motif2=${motif//-/_}
                                            substitution2=${substitution//-/_}
                                            grep -RilZ "$motif\\|$motif2" \
                                              | xargs --no-run-if-empty --null \
                                                  sed -i 's/'"$motif"'/'"$substitution"'/g;s/'"$motif2"'/'"$substitution2"'/g'
                                            
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              10 février 2023 à 11:09:10

                                              tu as l'air d'avoir compris, mais, moi, l'intérêt de faire rouges->bleues+bleues->rouges (dans les remplacements de paramètres shell) au lieu de bleues->rouges m'échappe encore.
                                              saurais-tu me l'expliquer, s'il te plaît ?

                                              au moins, il n'y a plus qu'une seule commande sed, et ça c'est bien. ;)

                                              • Partager sur Facebook
                                              • Partager sur Twitter

                                              Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                                                10 février 2023 à 12:30:06

                                                Au risque de me répéter,
                                                je doit remplacer 2 chaînes de caractère différentes.

                                                Elles se ressemblent, c'est ce qui doit te perturber.

                                                Si tu préfères, quelque soit l'entrée, par exemple: rouge+bleu+rouge,
                                                je doit faire une substitution avec rouge+rouge+rouge
                                                et une substitution avec bleu+bleu+bleu

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  10 février 2023 à 13:12:45

                                                  > Au risque de me répéter,

                                                  Au lieu de répéter, il faut raccorder à la situation

                                                  • le machin avec des tirets est remplacé par truc avec des tirets
                                                  • le machin avec des underscores est remplacé par truc avec des underscores
                                                  ca serait plus clair avec des variables bien nommées; par exemple substitutionTirets et substitutionUnderscores.

                                                  -
                                                  Edité par michelbillaud 10 février 2023 à 13:14:14

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    10 février 2023 à 14:44:47

                                                    je le comprendrais si ce n'était pas fait dans un même fichier, ou si les éléments à remplacer étaient différents*.
                                                    dans le cas présenté, la dernière substitution annule la précédente.

                                                    rouge remplace bleu
                                                    +
                                                    bleu remplace rouge
                                                    =
                                                    bleu remplace rouge

                                                    mais je manque certainement de contexte pour percevoir le besoin.

                                                    --

                                                    * rouge->bleu+bleu->vert

                                                    qui pourrait aussi faire l'objet d'une seule substitution : (rouge OU bleu) -> vert

                                                    sed 's/rouge\|bleu/vert/g'
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter

                                                    Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                                                      10 février 2023 à 16:58:04

                                                      Bon ...
                                                      affiche les variables après chaque instruction, tu comprendras peut-être ce qui se passe.
                                                      Moi, j'abandonne.
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        10 février 2023 à 17:13:19

                                                        bien sûr, après chaque instruction, mais à la fin du traitement de la fonction !?

                                                        dans le fichier final, ne subsistera que la dernière substitution.

                                                        c'est comme si tu codais :

                                                        echo -n a
                                                        echo -n b
                                                        echo c
                                                        

                                                        au lieu de

                                                        echo abc

                                                        en effet, après chaque instruction un seul caractère est affiché.

                                                        au final, la chaîne abc est affichée

                                                        il y a sûrement des trucs que tu ne nous dis pas, tant pis.

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter

                                                        Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                                                          10 février 2023 à 17:19:16

                                                          > il y a sûrement des trucs que tu ne nous dis pas, tant pis.

                                                          Il a déja dit qu'il y avait *deux* substitutions distinctes, sur des trucs différents, à effectuer dans chaque fichier.

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            10 février 2023 à 17:40:07

                                                            j'ai essayé de simplifier autant que possible mes explications pour mettre en évidence l'inutilité de la manœuvre.

                                                            montrez-moi, avant, pendant (si ça vous amuse), mais surtout après, que le résultat final est différent de la dernière substitution, je comprendrai peut-être. :)

                                                            ah, quand ça veut pas, ça veut pas.

                                                            -
                                                            Edité par dantonq 10 février 2023 à 17:45:57

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter

                                                            Validez la réponse utile « Un problème clairement exposé est à moitié résolu. » Pas de MP technique

                                                              11 février 2023 à 14:13:12

                                                              > tu as l'air d'avoir compris, mais, moi, l'intérêt de faire rouges->bleues+bleues->rouges (dans les remplacements de paramètres shell) au lieu de bleues->rouges m'échappe encore. saurais-tu me l'expliquer, s'il te plaît ?

                                                              Qui a dit que pluginName n'avait pas d'underscore à la base ? Franchement, je ne vois pas le problème à faire abstraction du caractère utilisé et ne pas se prendre la tête lorsqu'on écrit le nom du plugin.

                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              Script shell - substitution dans plusieurs fichier

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown