Forum général.général traitement par lot > conversion progressive

Posté par . Licence CC by-sa
1
4
juin
2014

Bonjour à tous.

Voilà j'ai 15 000 fichier jpeg répartit dans te très nombreux dossier et sous dossier sur lequel je souhaiterais appliquer un traitement (passer en JPEG progressive)

J'ai bien réussit à faire la fonction:
for i in *jpg ; do convert -strip -interlace Plane $i convert/$i ; done &

Mais coment pourrais je faire en sorte d'appliquer le traitement sur les sous-dossier

MErci

  • # une parmi des milliers de manières de le faire

    Posté par (page perso) . Évalué à 5. Dernière modification le 04/06/14 à 11:23.

    Je propose un truc incompréhensible et non testé :
    Un fichier à nommer Makefile écrit en 5 minutes (j'avais envie de me dérouiller sur cette syntaxe incroyable) :

        dstdir='converted'
        sources=$(shell find . -type f -name '*.jpg')
        targets=$(patsubst %, $(dstdir)/%, $(sources))
    
        all: $(targets)
    
        .PHONY: all
    
        $(dstdir)/%: %
            mkdir -p "$(@D)"
            convert -strip -interlace Plane $< $(@D)/$@

    Précision : toutes les indentations DOIVENT ÊTRE DES TABULATIONS.
    Ensuite, taper "make".

  • # find

    Posté par (page perso) . Évalué à 2.

    Si tu acceptes de modifier l'image d'origine, tu peux simplement utiliser mogrify.

    Sinon, tu peux faire une recherche avec find puis exécution avec convert…

    https://www.domotego.com/ | https://www.maccagnoni.eu/ | https://www.smm-informatique.fr/

  • # man find

    Posté par . Évalué à 4. Dernière modification le 04/06/14 à 12:20.

    for i in $(find . -name '*.jpg') ...

    • [^] # Re: man find

      Posté par . Évalué à 6.

      passera pas, avec 15000 fichier le bash va râler (ligne trop longue)
      par contre

      find -name '*.jpg' -exec convert -strip -interlace Plane {} convert/{} \;

      à plus de chance de marcher, mais il faudra au préalable creer la sous arborescence d'ou
      find -type d -exec mkdir -p convert/{} \;

      d'où la solution
      find -type d -exec mkdir -p convert/{} \;
      find -name '*.jpg' -exec convert -strip -interlace Plane {} convert/{} \;

      il est possible de faire en oneliner, mais je laisse les autre s'amuser aussi ;)

      Il ne faut pas décorner les boeufs avant d'avoir semé le vent

      • [^] # Re: man find

        Posté par (page perso) . Évalué à 3.

        C'est la meilleure solution, mais…

        … fais attention à bien traiter les noms de fichiers avec l'option -print0. Bon, et je te conseille d'utiliser xargs en lieu et place de -exec, ce qui permettra potentiellement d’accélérer les choses, et de ne pas t'embêter à échapper des trucs…

        Je te propose donc:

        find -type d -print0 | xargs -I {} -0 mkdir -p convert/{};
        find -name '*.jpg' -print0 | xargs -I {} -0 convert -strip -interlace Plane {} convert/{};
  • # find + boucle while

    Posté par . Évalué à 1. Dernière modification le 04/06/14 à 18:03.

    find . -type f -name *.jpeg |
    while read i; do
      mkdir -p ../convert/$(dirname "$i")
      convert -strip -interlace Plane "$i" ../convert/"$i"
    done
    

    (pas testé)

    J'utilise ça tout le temps, je trouve que c'est plus lisible que le find -exec ou le | xargs

    • [^] # Re: find + boucle while

      Posté par (page perso) . Évalué à 3.

      J'utilise ça tout le temps

      Donc tu n'as aucun fichier dont le nom contient d'espace.

      find . -type f -name *.jpeg -print0 |
      while read -d '' -r i; do
        mkdir -p ../convert/$(dirname "$i")
        convert -strip -interlace Plane "$i" ../convert/"$i"
      done

      Le -d remplace avantageusement le IFS=

      La même chose sans créer de sous-shell au sein de la boucle (propre à Bash je pense):

      while read -d '' -r i; do
        mkdir -p ../convert/$(dirname "$i")
        convert -strip -interlace Plane "$i" ../convert/"$i"
      done < <(find . -type f -name *.jpeg -print0)
      • [^] # Re: find + boucle while

        Posté par . Évalué à 3.

        chez moi find … | read fonctionne même avec des espaces, read lisant la totalité de la ligne

        Il ne faut pas décorner les boeufs avant d'avoir semé le vent

        • [^] # Re: find + boucle while

          Posté par (page perso) . Évalué à 2.

          Exact. Ce sont les caractères « très merdiques » qui posent problème. Par exemple un \n dans un nom de fichier.
          Disons que sur une machine « amie » on n'en rencontre jamais.

  • # parallel

    Posté par . Évalué à 3.

    je suis assez fan de gnu/parallel car tu peux:
    - contrôler finement le nombre de jobs en parallèle.
    - faire un lancement à blanc (dry run) qui ne lance pas les jobs mais te montre ce qui serai lancé.
    - utiliser des substitutions pour utiliser le répertoire racine, le nom du fichier, sans extension, etc.
    - faire des choses beaucoup plus avancées : lancement sur plusieurs serveur, reprise sur arrêt.

    La doc est plutôt complète.

    Fais un petit essai avec:

    parallel -n 1 echo {} {/} {//} {.} :::: <(find . -type f -name "*.jpg")

Suivre le flux des commentaires

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