[shell] problème avec boucle find et espaces

Vic -  
 vic007 -
Bonjour,
Petit soucis avec un script (qui doit remplacer le caractère  par _ dans tous les noms de fichier .jpg des sous répertoires du répertoire courant... pfiou !):
for f in `find . -type f -name "*.jpg" `; do
     mv -T "$f" "${f/Â/_}"
done


En fait, le soucis que j'ai, c'est que à un moment (peut-être dans le find), les noms des fichiers et des répertoires sont décomposés car ils contiennent des espaces et le shell me sort ca :
mv: ne peut évaluer `./300': Aucun fichier ou répertoire de ce type
mv: ne peut évaluer `de': Aucun fichier ou répertoire de ce type
mv: ne peut évaluer `Frank': Aucun fichier ou répertoire de ce type
mv: ne peut évaluer `Miller': Aucun fichier ou répertoire de ce type
mv: ne peut évaluer `2007/300': Aucun fichier ou répertoire de ce type
mv: ne peut évaluer `Comic': Aucun fichier ou répertoire de ce type
mv: ne peut évaluer `Con': Aucun fichier ou répertoire de ce type
mv: ne peut évaluer `2006/300Comicon_044.jpg': Aucun fichier ou répertoire de ce type
mv: ne peut évaluer `./300': Aucun fichier ou répertoire de ce type
mv: ne peut évaluer `de': Aucun fichier ou répertoire de ce type
mv: ne peut évaluer `Frank': Aucun fichier ou répertoire de ce type
mv: ne peut évaluer `Miller': Aucun fichier ou répertoire de ce type


Ca doit être bien facile à trouver, mais la... je bloque :(
QUelqu'un peut-il m'éclairer?

Merci d'avance!
Configuration: Windows Vista
Internet Explorer 7.0

14 réponses

  1. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898
     
    Salut,

    En fait oui c'est bien une histoire d'espace, dû non pas à la commande "find" mais à la boucle "for" et plus particulièrement à la valeur de la variable d'environnement "$IFS" (Input Field Separator), qui par défaut a pour valeur l'espace et tabulation et à qui il faut assigner la valeur "saut de ligne" (\n) :
    OLD_IFS="$IFS"
    IFS=$'\n'
    for f in $(find . -type f -name "*.jpg"=; do
         mv -T "$f" "${f/Â/_}"
    done
    IFS="$OLD_IFS"
    Devrait marcher bien mieux.
    Sinon une autre façon de faire est passer par une boucle "while", voir à ce sujet cette astuce dans la FAQ.

    ;-))
    4
  2. Vic
     
    Ah super ! Merci, je connaissais pas ça... enfin c'est pas étonnant, j'ai raté quelques cours de shell :p
    Sinon j'ai un autre soucis du coup... j'aimerais remplacer le caractère ° par _ dans ma boucle précédente... mais on dirait que cela ne fonctionne pas, car aucun fichier n'est modifié... Pourtant j'utilise la même boucle :
    for f in `find . -type f -name "*.jpg" `; do
         mv -T "$f" "${f/°/_}"
    done
    0
    1. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898
       
      Il faut protéger l'étoile ( \* ) qui est un méta-caractère (ou joker si tu veux) afin qu'il ne soit pas interprété comme tel et lui rendre son sens littéral :
      mv -T "$f" "${f/\°/_}"
      ;-))
      0
  3. Vic007
     
    En fait je dois être nouille mais cela ne marche pas :
    for f in `find . -type f -name "*.jpg" `; do
         mv -T "$f" "${f/\°/_}"
    done


    Aucun fichier n'est modifié :(

    Please help!!!
    0
  4. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898
     
    Attends là ! Faudrait qu'on se comprenne bien :-\

    Le caractère " * " se trouve bien dans le nom de tes fichiers ? Ou tu me parles d'autre chose !?
    [tmpfs]$ var="mon * étoile"
    [tmpfs]$ echo "$var"
    mon * étoile
    [tmpfs]$ echo ${var/\*/_}
    mon _ étoile
    [tmpfs]$  
    ;-)

    0
    1. Vic007
       
      lol en fait non on se comprend pas bien, le caractère que je veux remplacer c'est un °, le ° de numéro ... :)
      0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898
     
    Arf désolé, problème d'affichage ;-((
    Bon mais en fait ça change pas grand chose :
    [tmpfs]$ var="mon n° à moi"
    [tmpfs]$ echo ${var/°/_}
    mon n_ à moi
    Si tu as des problèmes, affiches un exemple avec ton code et l'erreur générée.
    0
    1. Vic007
       
      en fait voici mon code
      for f in `find . -type f -name "*.jpg" `; do
           mv -T "$f" "${f/°/_}"
      done


      ca marchait avec

      for f in `find . -type f -name "*.jpg" `; do
           mv -T "$f" "${f/Â/_}"
      done


      et là non :(
      0
  7. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898
     
    Et les noms de tes fichiers dans le répertoire ils ressemble à quoi ?

    Affiche un listing s'il te plaît "ls -1" (c'est un 1 (chiffre un) et pas un L minuscule, hein ?)
    0
  8. Vic007
     
    Jury_n_°001.jpg
    Jury_n_°002.jpg
    Jury_n_°003.jpg
    Jury_n_°004.jpg
    Jury_n_°005.jpg
    Jury_n_°006.jpg
    ...
    Jury_n_°021.jpg
    Jury_n_°022.jpg
    
    0
  9. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898
     
    Ben je comprends pas non plus ;-\
    [tmpfs]$ touch Jury_n_°00{1,2,3,4,5}.jpg
    [tmpfs]$ ls -1
    Jury_n_°001.jpg
    Jury_n_°002.jpg
    Jury_n_°003.jpg
    Jury_n_°004.jpg
    Jury_n_°005.jpg
    
    [tmpfs]$ for f in *; do mv "$f" ${f/°/_}; done
    [tmpfs]$ ls -1
    Jury_n__001.jpg
    Jury_n__002.jpg
    Jury_n__003.jpg
    Jury_n__004.jpg
    Jury_n__005.jpg
    
    [tmpfs]$
    Essaie d'exécuter ton script en mode débogage, ajoute "set -xv" après la ligne "shebang" (#! /bin/bash) et essaie de repérer où ça coince...
    0
    1. Vic007
       
      voila la sortie :

       for f in `find . -type f -name "*.jpg" `; do      mv -T "$f" "${f/\°/_}"; done
      for f in `find . -type f -name "*.jpg" `; do      mv -T "$f" "${f/\°/_}"; done
      find . -type f -name "*.jpg"
      ++ find . -type f -name '*.jpg'
      echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"
      0
  10. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Salut,

    ça ne te conviens pas la commande rename ?
    rename 's/_\W/__/' Jury*.jpg
    0
  11. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898
     
    Ce n'est pas la peine d'échapper le "°" (${f/\°/_}), ce n'est pas un méta-caractère du shell !

    Il ne te renvoie que ça comme sortie le débogage ?
    Il en manque là, non ?
    0
  12. Vic007
     
    heu non rename ca va pas trop, car les noms de fichiers sont jamais idnetiques, à part dans cet exemple....
    0
  13. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    car les noms de fichiers sont jamais idnetiques, à part dans cet exemple
    ben, justement, on peut utiliser les regex et c'est très puissant
    si on reviens à ton problème de début remplacer le caractère  par _ dans tous les noms de fichier .jpg on aura ça

    rename 's/\xC2/_/' *.jpg

    0
    1. Vic007
       
      ah ok !!! alors ca c'est correcte?

      for f in `find . -type f`; do
          rename 's/°/_/' *.jpg
      done
      0
  14. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    find . -name '*.jpg' -exec rename 's/°/_/' {} \;
    mais il faut voir qu'il s'agit bien de °il faut voir le code ascii de ce caractère pour être sur qu'on cherche le bon caractère
    0
  15. vic007
     
    en fait le soucis vient de là je pense, c'est que je n'utilisais pas le code ascii du caractère °...
    Bon ben merci à tous, je vais tester cela, et je vous tiendrais au courant... histoire d'aider un jour un galérien comme moi :)
    0