Script bash : boucle for et espace

Vence -  
lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   -
Bonjour,

J'essaie d'utiliser une boucle for avec des noms de fichier comme ceci :
for i in `ls *.jpg`
do
  echo $i
done


Tout ce passe bien sauf si mes noms de fichiers contiennent des espaces (ce qui est normal puisqu'il utilise les espaces pour séparer les variables)
Auriez vous une solution ?

Vence
Configuration: Linux
Firefox 3.0.11

4 réponses

  1. sluthole
     
    Bonjour,

    Comme disais lamij20 : "C'est normal vu que l'espace est un caractère spécial pour le shell. L'espace sépare les commandes des options, des arguments, etc. "

    Pour info, on peut aussi jouer avec ce séparateur de champ (IFS) en le modifiant avec par ex :

    IFS=$'\n\t'
    for i in `ls *.jpg`
    do
    echo $i
    done
    unset IFS

    Cdlt, Marc
    5
    1. foobar47 Messages postés 13654 Statut Contributeur 534
       
      Bonjour,

      Ta solution fonctionne également.

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

    Il suffit de double quoter les variables :
    [tmpfs]$ ls -1
    mon autre fichier.jpg
    mon autre fichier.txt
    mon fichier.jpg
    mon fichier.txt
    
    [tmpfs]$ for fich in *.jpg; do echo "$fich"; done
    mon autre fichier.jpg
    mon fichier.jpg
    
    [tmpfs]$
    ;-))
    3
    1. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
       
      Salut,

      Aux guillemets j'ai pensé d'abord mais comme ça ne marchais pas avec ls je n'ai plus pensé tout simplement à for i in *.jpg ;-)))
      0
      1. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898 > lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention  
         
        Là est toute la complexité des langages informatique ;-((
        0
    2. kissvcool
       
      L'avatage de cette solution en dehors de la simplicité, c'est que comparer a l'utisation de
      tr " " "_"'
      il n'y a pas de perte d'information, puisque substituer les espaces par un caractère ne permet plus d'identifier le fichier de base si son nom contenait à la base déjà ce caractère.
      0
    3. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
       
      Salut,

      si son nom contenait à la base déjà ce caractère.
      Oui, effectivement ;-)
      0
  3. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Salut,

    C'est normal vu que l'espace est un caractère spécial pour le shell. L'espace sépare les commandes des options, des arguments, etc.

    Voici un exemple
    lami20j@debian:~$ ls *.jpg
    aa aa.jpg  bb bb.jpg  capture1.jpg  capture2.jpg


    Donc quand tu fais for i in $(ls *.jpg) shell vois ça
    for i in aa aa.jpg  bb bb.jpg  capture1.jpg  capture2.jpg


    Donc il va affiche chaque élément séparé par espace.

    Voici une manière de le faire
    lami20j@debian:~$ ls *.jpg
    aa aa.jpg  bb bb.jpg  capture1.jpg  capture2.jpg
    lami20j@debian:~$ for i in `ls *.jpg|tr " " "_"`; do echo ${i/_/ }; done
    aa aa.jpg
    bb bb.jpg
    capture1.jpg
    capture2.jpg
    


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

      Oops; trop tard ;-((
      0
      1. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571 > jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention  
         
        Re,

        Pas du tout.
        Ta solution est meilleure ;-)
        En revanche les deux solutions, lui permettre de comprendre ce qui se passe en fait ;-)
        0
      2. Vence > lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention  
         
        Merci pour vos deux solutions. Effectivement je n'avais pas penser à utiliser directement les caractères joker et laisser le bash gérer tout ça sans passer par le ls.

        Par contre si d'aventure c'était des *.sh que je listais, ne risquerait-il pas d'exécuter directement les scripts 'listés' ? Auquel cas vaudrait mieux la première solution, non ?

        Vence
        0
      3. jipicy Messages postés 40842 Date d'inscription   Statut Modérateur Dernière intervention   4 898 > Vence
         
        Si tu ne les lances pas explicitement (./script.sh ou sh script.sh) et ne fais que les afficher, pas de soucis ;-))
        0
      4. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571 > Vence
         
        Salut,

        Je ne pense pas que tu risques quelque chose en faisant echo mon script.sh
        En ce qui concerne les solutions, tu choisis celle qui te conviens le mieux en fonction de situation.
        0
  4. Vence
     
    J'ai oublié de préciser que du coup si les fichiers contiennent des espaces ça ne "marche" plus (le echo renvoye for justement le bout séparé par des espaces). Or je souhaiterais avoir l'intégralité du nom du fichier. Dois je faire des concaténations jusqu'à avoir un nom de fichier (contenant un . par exemple) ?
    0