Partage
  • Partager sur Facebook
  • Partager sur Twitter

Solution multirenommage.sh

Cours linux chapitre "Les boucles"

Sujet résolu
    14 mars 2022 à 16:18:59

    Voici ma solution pour l'exercice : "Création d'un script de multirenommage.sh". Pour le cours : Reprendre le contrôle avec Linux, partie 5, chapitre 5 Les boucles.

    Cela marche normalement à tous les coups, j'ai bien galérer pour éditer ce code ^^

    ATTENTION ! Lorsque que vous lancez la commande et que vous voulez préciser le paramètre, il faut mettre ce dernier entre guillemets ! Par exemple "*.txt" ou encore "*.csv" pour signifier que l'on veut renommer tous les fichiers portant telle ou telle extension !

    J'espère que cela aidera ceux qui comme moi ont pu ou pourront galérer sur cet exercice !

    • Partager sur Facebook
    • Partager sur Twitter
      14 mars 2022 à 16:39:48

      c'est une très mauvaise solution :

      • imagine que l'un des fichiers s'appelle fi chier.txt
      • il ne devrait pas être nécessaire d'indiquer le Développement de chemins (l'astérisque), mais uniquement l'extension
      • et si j'indique plusieurs fichiers au read ?
      • etc... 

      et c'est aussi une très mauvaise présentation : il aurait été mieux venu de poster un copier/coller du code plutôt qu'une capture d'écran

      -
      Edité par dantonq 14 mars 2022 à 17:14:24

      • Partager sur Facebook
      • Partager sur Twitter

      "Un problème clairement exposé est à moitié résolu." ·· Pas de questions techniques en MP.

        14 mars 2022 à 18:06:35

        Aucun soucis de mon côté concernant ces points.

        J'ai fait exprès d'avoir des fichiers qui ne contiennent pas d'espace dans ma console. 

        Il est clairement indiqué dans le cours qu'il faut utiliser une * pour que tous les fichiers soient modifiés.

        ./multirenommage.sh *.txt

        https://openclassrooms.com/fr/courses/43538-reprenez-le-controle-a-laide-de-linux/43464-les-boucles#/id/r-2284731

        Je peux sans problèmes indiquer plusieurs fichier à modifier une fois que le prompt read apparaît.

        Quelle aurait été la différence si j'avais fait un copier/coller ?

        N'ayant pas vu de réponse claire sur le forum concernant l'énoncé de ce cours j'ai jugé bienvenue de présenter la mienne qui fonctionne de mon côté. Il est certains que le code peut être grandement amélioré mais faute de mieux pour le moment...

        Si vous avez de meilleures solutions et/ou améliorations à me donner, je serais enchanté de les lire et de les appliquer !

        -
        Edité par MaximePrigent29 14 mars 2022 à 18:38:03

        • Partager sur Facebook
        • Partager sur Twitter
          14 mars 2022 à 18:49:42

          Quelle aurait été la différence si j'avais fait un copier/coller ?

          je pourrais le lire sans avoir à deviner ce qui se cache dans les couleurs sombres sur fond noir.
          mais je vois quand même qu'il n'y a pas de guillemets, alors qu'il faut toujours mettre des guillemets autour des Développement de paramètres.

          des noms de fichiers avec des espaces, ça peut arriver, il faut en tenir compte.

          l'énoncé est, tu l'as souligné (il faut ajouter des guillemets), erroné.

          explique-nous comment plusieurs fichiers indiqués au seul et même read pourraient être renommés correctement : une seule variable contient tous les noms, et il n'y a qu'un suffixe !

          • Partager sur Facebook
          • Partager sur Twitter

          "Un problème clairement exposé est à moitié résolu." ·· Pas de questions techniques en MP.

            14 mars 2022 à 21:40:41

            Très bien, dans ce cas dites-moi comment je peux améliorer la partie "read" de mon script pour que l'on puisse nommer plus d'un fichier à modifier.
            • Partager sur Facebook
            • Partager sur Twitter
              15 mars 2022 à 2:33:35

              tu peux faire une boucle while, qui teste une variable (assignée par un autre read), et qui se répète tant que cette variable vérifie une valeur prédéfinie.

              goOn=vrai
              tant que goOn == vrai
              faire
                  lire nomFichier
                  si estUnFichier nomFichier
                  alors renommer nomFichier nomFichierSuffixe
                  finSi
              
                  lire goOn
              
              finTantQue



              • Partager sur Facebook
              • Partager sur Twitter

              "Un problème clairement exposé est à moitié résolu." ·· Pas de questions techniques en MP.

                15 mars 2022 à 8:24:39

                J'ai cogité là-dessus cette nuit et je me suis également dit que je pouvais insérer un while de tel manière que tant que l'on nomme un fichier en read la boucle recommence, et de faire en sorte qu'elle s'arrête définitivement si on tape un mot défini au préalable du style "fini".

                Le souci c'est que j'arrive à faire tourner la boucle pour qu'elle ne s'arrête que si on tape le mot "fini" dans le read. Mais je n'arrive pas à faire en sorte que si on tape le nom d'un fichier ce dernier soit modifié.
                while [ "$reponse" != 'fini' ]; do
                        read -p 'Entrez le fichier à renommer sinon tapez fini pour quitter : ' reponse
                                if [ $reponse = 'fichier' ]; then
                                mv $fichier $fichier-réussi
                                fi
                done

                -
                Edité par MaximePrigent29 16 mars 2022 à 8:42:47

                • Partager sur Facebook
                • Partager sur Twitter
                  19 mars 2022 à 12:00:42

                  Alors pour vérifier que c'est un fichier, il faut utiliser test (cf. man test):

                  cheminFichier="/chemin/vers/mon/fichier"
                  test -f "$cheminFichier"
                  # Ou autre syntax
                  [ -f "$cheminFichier" ]
                  

                  Sinon, tu peux aussi utiliser des commandes qui savent mieux gérer tous les cas particuliers, comme find:

                  #!/usr/bin/env bash
                  
                  while [ -n "$1" ]; do
                      find -name "$1" -exec cp {} {}-copy \;
                      shift 1
                  done
                  

                  C'est pas le plus efficace, ni le plus "pure", mais c'est très simple et facile à utiliser:

                  $ ls                
                  file1  file2  file3  file4.txt  file5.txt  file6.csv  multirename.sh
                  $ $ bash -x ./multirename.sh "file 1" "file[1-2]" "*.txt" *.csv
                  + '[' -n 'file 1' ']'
                  + find -name 'file 1' -exec cp '{}' '{}-copy' ';'
                  + shift 1
                  + '[' -n 'file[1-2]' ']'
                  + find -name 'file[1-2]' -exec cp '{}' '{}-copy' ';'
                  + shift 1
                  + '[' -n '*.txt' ']'
                  + find -name '*.txt' -exec cp '{}' '{}-copy' ';'
                  + shift 1
                  + '[' -n file6.csv ']'
                  + find -name file6.csv -exec cp '{}' '{}-copy' ';'
                  + shift 1
                  + '[' -n '' ']'
                  $ ls                                                         
                  file1  file1-copy  file2  file2-copy  file3  file4.txt  file4.txt-copy  file5.txt  file5.txt-copy  file6.csv  file6.csv-copy  multirename.sh
                  

                  On peut directement utiliser le globbing du shell et passer plusieurs arguments.

                  Faire un script interactif est souvent plus pénible et lourd.


                  • Partager sur Facebook
                  • Partager sur Twitter
                    20 mars 2022 à 11:19:19

                    Ton script n'a pas l'air plus utile qu'un simple mv [TARGET] [CIBLE], du coup je doute de la réelle utilité...En général on scripte pour automatiser des tâches.

                    Donc demander un prompt ( via un shell) pour cette simple opération semble vraiment inutile.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      20 mars 2022 à 11:27:04

                      C'est un exercice proposé à ceux qui débutent sur Linux. C'est pas fait pour être utile réellement.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        30 mars 2022 à 14:03:19

                        Pour rappel voici la page de l'énoncé de l'exercice du cours : "Reprenez le contrôle à l'aide de Linux"

                        https://openclassrooms.com/fr/courses/43538-reprenez-le-controle-a-laide-de-linux/43536-tp-generateur-de-galerie-dimages
                        • Partager sur Facebook
                        • Partager sur Twitter
                          30 mars 2022 à 16:45:54

                          À vous de jouer ! Essayez de créer un script multirenommage.sh, reposant sur ce principe, qui va rajouter le suffixe -old… uniquement aux fichiers qui correspondent au paramètre envoyé par l'utilisateur !

                          ./multirenommage.sh *.txt

                          Si aucun paramètre n'est envoyé, vous demanderez à l'utilisateur de saisir le nom des fichiers à renommer avec read.

                          il y a une ambiguïté sur ce que l'auteur appelle un paramètre. Je préfère le terme d'argument, et je réserve le terme de paramètre aux paramètres positionnels.

                          Ici, l'argument *.txt sera interprété par le shell avant de l'être par le script, et le script recevra, en paramètres, la liste des fichiers résultant du Développement des chemins induit par l'astérisque.

                          le script devra donc, après avoir vérifié qu'il y a bien au moins un paramètre positionnel, faire une bête boucle for sur la liste de ces paramètres.

                          mais bon, il ne faut pas trop attendre d'un tuto sur la programmation shell, qui ne met pas les guillemets nécessaires, préconise des boucle for sur Substitution de commandes, et emploie ls dans ses exemples de scripts. :(

                          -
                          Edité par dantonq 30 mars 2022 à 16:46:24

                          • Partager sur Facebook
                          • Partager sur Twitter

                          "Un problème clairement exposé est à moitié résolu." ·· Pas de questions techniques en MP.

                            3 avril 2022 à 17:57:25

                            N'oublie pas que si tu exécutes du bash, déclaré en début de script tu as des options de debugging et autres.

                            On parle bien d'arguments aussi pour ce qu'on va ordonner à bash.

                            Tu peux très bien commencer ton script avec des options ou arguments de la commande #!/bin/bash

                            Commencer par #/bin/bash -ex par exemple engage un mode debugging, ou verbose, parce que -x ou -v sont plus ou moins équivalents...Tu seras paré à d'éventuels script à déboguer. (le -e c'est exit si erreur, ça peut servir aussi)

                            Sinon après privilégie les noms de fonctions (bash aime travailler en fonctions), pour du code propre. Même si ce n'est que du bash ça évitera des commentaires inutiles ou ce genre de choses à scripter.

                            • Partager sur Facebook
                            • Partager sur Twitter
                              3 avril 2022 à 19:53:38

                              On parle bien d'arguments aussi pour ce qu'on va ordonner à bash.

                              des "instructions" ?

                              • Partager sur Facebook
                              • Partager sur Twitter

                              "Un problème clairement exposé est à moitié résolu." ·· Pas de questions techniques en MP.

                                4 avril 2022 à 15:28:55

                                dantonq a écrit:

                                On parle bien d'arguments aussi pour ce qu'on va ordonner à bash.

                                des "instructions" ?


                                Oui mais je parlais de la façon dont on lance le programme bash avant tout.

                                Sinon oui c'est du code avec des fonctions et des arguments aux fonctions, et du script.

                                J'ai tendance à garder le mot "instructions" pour du très bas niveau perso. Du coup je nomme ça code? A vrai dire je sais pas si tout ça est normé, les appellations en tout cas. :)

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  4 avril 2022 à 15:56:56

                                  dans le script, les arguments passés aux scripts
                                  ./monScript arg1 arg2 "arg n+1"
                                  sont définis comme des paramètres positionnels
                                  $@ #le tableau de tous les arguments
                                  $1 # le premier argument : arg1
                                  ${10} #le dixième, avec les accolades sinon le shell ne le reconnaît pas, et lit le premier argument suivi d'un zéro.

                                  l'expression "paramètre positionnel", ça c'est "normalisé".
                                  c'est pourquoi j'essaie d'introduire une distinction avec ce qui est à l'extérieur du script.

                                  "instruction" sonne, en effet, plus bas niveau. Je ne comprenais pas ta phrase.

                                  "code", correspond àmha plus à un ensemble de commandes

                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  "Un problème clairement exposé est à moitié résolu." ·· Pas de questions techniques en MP.

                                  Solution multirenommage.sh

                                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                  • Editeur
                                  • Markdown