Retourner aux forums || Retourner au forum Programmation.shell

Programmation.shell : appliquer une action à chaque fichier d'un répertoire

Posté par Thomas DEBESSE (page perso, ) le 24 août 2006
0
Énoncé du problème : j'ai un nombre de fichiers auxquels je voudrais appliquer la même opération, le tout par l'intermédiaire d'un script.
Au début j'avais pensé à faire comme ceci :

#!/bin/sh
list=`ls *.jpg`
for i in $list
do
  macommande $i
done


Mais ça ne marche pas pour les fichiers qui ont des espaces dans leur noms.
Forcément si j'ai deux fichiers "fleur.jpg" et "chauve souris.jpg" il va vouloir me traiter trois fichiers appelés "fleur.jpg", "chauve" et "souris.jpg".

Voilà, si vous avez une méthode simple et efficace je suis preneur :)
Merci.

--
† In te confirmátus sum ex útero : de ventre matris meæ tu es protéctor meus.
> Lire le message (10 commentaires, moyenne: 2,2).  

Cette discussion est archivée, il n'est plus possible de laisser des commentaires.

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.

""

Posté par schyzomarijks () le 24/08/2006 à 15:23. (lien). Évalué à 5.

macommande "$i"

sinon find est ton ami.

find . -type f -exec macommand '{}' \;

--
OO watching you !!!
  • [^]Re: "" => Pareil avec maxdepth et mindepth

    Posté par Steve Azriel () le 24/08/2006 à 15:54. (lien). Évalué à 2.

    Bonjour,

    Juste pour ajouter que find peut travailler sur différents niveaux de profondeur (voir la page man/info).
    Donc, soit find parcourt un répertoire et tous ses sous-répertoires (cas par défaut), soit tu lui fixes des limites ;-)

    Cdlt,

  • [^]Re: ""

    Posté par Pierre Maziere () le 24/08/2006 à 15:56. (lien). Évalué à 1.

    le coup des guillemets ne marche pas car le for recupere tous les séquences de lettres de $list ne contenant pas d'espaces.
    Du coup ton $i ne contient jamais d'espace et tu te retrouves au point depart.

    le find est bcp plus approprie

    • [^]-print0

      Posté par daggett () le 24/08/2006 à 20:42. (lien). Évalué à 2.

      Pour contourner tout type de caractères pénible (y compris guillemets et quotes): combiner "-print0" de find et "-0" de xargs, pour utiliser le caractère nul \0 comme séparateur.
      Apres tu peux faire un truc du genre:


      find . -maxdepth 1 -type f -name \*.jpg -print0 | xargs -0 -n 1 macommande


      (le -n1 de xargs servant à appeler la commande pour 1 fichier à la fois)
      De cette façon les noms de fichiers sont transmis via pipe à xargs et celui-ci construit directement les arguments de la commande, sans jamais passer par les interprétations éventuelles du shell.

  • [^]Les guillemets c'est bien si on les met partout où c'est nécessaire

    Posté par liberforce (Jabber id, page perso, ) le 24/08/2006 à 22:45. (lien). Évalué à 2.

    #!/bin/sh
    list=`ls *.jpg`
    for i in "$list"
    <-- guillemets
    do
       macommande "$i"
    <-- guillemets
    done


    ou plus simplement:

    #!/bin/sh
    for i in *.jpg
    do
       macommande "$i"
    <-- guillemets
    done


    Remplace macommande par un simple echo pour voir ce que ça donne...

retirer_ces_$*%*&@_d'_espaces !!

Posté par Farvardin (page perso, ) le 24/08/2006 à 15:27. (lien). Évalué à 2.

j'ai trouvé ce petit script bash pour retirer tous les espaces dans les noms de fichiers :


for i in *" "* ; do
j=`echo $i | sed -e 's/ /_/g' `
mv "$i" "$j"
done



1. soit tu l'utilises pour retirer_ces_$*%*&@_d'_espaces !!
2. soit tu le modifies pour l'inclure comme un filtre dans ton script (si c'est possible)
3. soit tu l'utilises tel quel comme en 1, puis ton script, et retraite tes fichiers en inversant le sed ( sed -e 's/_//g' ) si tu veux rajouter ces *$%***@& d'espaces qui n'ont rien à faire dans un nom de fichier :)

(désolé d'être grossier :) )

--
You can't grep dead trees...
  • [^]Re: retirer_ces_$*%*&@_d'_espaces !!

    Posté par schyzomarijks () le 24/08/2006 à 15:36. (lien). Évalué à 2.

    oui mais non, si tu fais le script inverse, un fichier qui contenait un tiret va se retrouver avec un espace.

    autant gérer le problème et mettre des guillemets autour de "$i"

    --
    OO watching you !!!
    • [^]Re: retirer_ces_$*%*&@_d'_espaces !!

      Posté par Thomas DEBESSE (page perso, ) le 24/08/2006 à 16:19. (lien). Évalué à 1.

      Comme dit plus haut mettre des guillemets autour du $i ne change rien, c'est au niveau du for que c'est découpé au niveau des espaces, et même si je fais joujou pour mettre chaque nom de fichiers entre guillemets, ça me fait pareil (un fichier "chauve et un fichier souris.jpg").
      Le find fonctionne, mais ça reste problèmatique si je veux effectuer plus d'une commande, voir des tests, des boucles, avec le nom du fichier.

      Exemple pratique : renommer une série de photo par la date contenue dans les infos exif de l'image.
      Si il y a des photos prises en rafale, plusieurs photos auront le même nom (prises à la même seconde), donc il faut que je puisse gérer le cas où une photo ayant ce nom existe déjà, alors rajouter et incrémenter un nombre dans le nom.

      Je ne peux pas me contenter de faire un
      find -name "*.jpg" -exec mv '{}' `récuperer-la-date`.jpg
      Il faut que je puisse sortir une liste de fichier, et tous les traiter un par un comme je veux, pas que ce soit find qui exécute mes commandes (ce qui est assez limité).

      À la rigueur il y a peut être moyen de faire un ls *.jpg > /tmp/plop
      et pour chaque ligne du fichier /tmp/plop, faire mes traitements, mais comment lire ligne après ligne le fichier /tmp/plop ?
      En gros faire une boucle :

      tant_que pas fin du fichier $i = nouvelle ligne
        exécuter ceci
        tester cela et faire ça sinon faire ceci
      fin_tant_que

      Merci

      --
      † In te confirmátus sum ex útero : de ventre matris meæ tu es protéctor meus.
      • [^]Re: retirer_ces_$*%*&@_d'_espaces !!

        Posté par schyzomarijks () le 24/08/2006 à 17:26. (lien). Évalué à 2.

        find -name "*.jpg" -exec macommand '{}' ;

        Tu sais, macommand peut très bien être un script qui fait ce que tu dis.

        par exemple. (largement améliorable)


        #!/bin/sh
        if [ -a "$1" ]; then
        date_exif=20061201
        new_name="$date_exif.jpg"
        counter="0"
        while [ -a "$new_name" ]; do
        counter=$[$counter+1]
        new_name="$date_exif-$counter.jpg"
        done
        mv "$1" "$new_name"
        else
        echo "paramètre incorrecte";
        exit -1;
        fi

        --
        OO watching you !!!

variable IFS du bash

Posté par B. franck () le 24/08/2006 à 20:14. (lien). Évalué à 2.

préciser IFS=$'\n' avant la formation de la liste fera que les éléments seront séparés par un retour à la ligne et pas des espaces. Il sera alors très simple de parcourir la liste sans se soucier des espaces.

Revenir en haut de page || Retourner aux forums || Retourner au forum Programmation.shell