Forum Programmation.shell renommer les fichier par script en nom_dossier_jour.jpg

Posté par  .
Étiquettes : aucune
1
6
jan.
2010

Bonjour à tous,

Voilà j'ai développer un petit script qui me permet de traiter mes image par lots, (redimensionnement, fusionnement,...)

mais je bute sur une chose j'aimerais encore qu'il renomme tout les images par
nom_dossier_jourmois_01.jpg
exemple:
dans le dossier (fiche technique) le 1janvier fiche_technique_0101_01.jpg
ou encore
dossier (image de coupe) le 4mars image_de_coupe_0403_01.jpg, image_de_coupe_02.jpg...

Mais j'ai un peu de mal pour récupérer le nom du dossier
Si quelque pouvais m'aidez ca serais génial.

Merci à vous



# Nom du nouveau répertoire
NV_DOSSIER=reduc

# Création du nouveau dossier s'il n'existe pas
if [ -d $NV_DOSSIER ] ;
then
echo "Le dossier reduc existe déjà"
else
mkdir $NV_DOSSIER
fi

# Pour toutes les photos (JPG) du répertoire
for i in *.[jJ][pP][gG] ;
do
# Réduit l'image en 601x400
convert "$i" -resize 601x400 "$NV_DOSSIER/$i"
# fusione l'image avec un calque contenant les coins
composite -gravity center /home/sacha/Bureau/cadre.png "$NV_DOSSIER/$i" "$NV_DOSSIER/$i"
# fin de la boucle FOR
done

cd "$NV_DOSSIER"
# mise a zero (1) du compteur
num=1

for image in *[jJ][pP][gG]; do
mv "$image" "fruit_$(date +'%d%m')_00${num}.jpg"
((num=num+1))
done


au dernier stade j'arrive à récupérer via pwd le dossier courant:

/home/sacha/Bureau/images/test image 2/


mais j'aimerai le transformer en
test_image_2
et là je bloque.

Merci à vous
  • # sed, awk, rename

    Posté par  . Évalué à 2.

    pour change un motif en un autre.

    rename de fait carrement le deplacement (à partir d'une motif) et dois donc pouvoir changer les motifs à la volée

    sinon tu as les classiques sed ou awk pour chercher/remplacer les espaces et les changer en _
  • # Re:

    Posté par  (site web personnel) . Évalué à 2.

    basename $(pwd)

    Pour le mv, pour enlever le 00$num tout moche :

    nv_nom=$(printf fruit_%s_%.4d $(data +%d%m) $num)
    mv "$image" $nv_nom
    • [^] # Re: Re:

      Posté par  . Évalué à 3.

      Le problème pourra venir des espaces dans les noms de dossier. Utilise les guillements
      basename "$(pwd)"

      Pour remplacer les espaces par des underscores, plutôt que sed et awk, le plus pratique, c'est d'utiliser les fonctions de remplacement du shell
      ${variable// /_}

      Au final, ça donne
      cd "/home/sacha/Bureau/images/test image 2"
      name=${basename "$(pwd)"}
      name=${name// /_}
      echo $name
      => test_image_2
      • [^] # Re: Re:

        Posté par  (site web personnel) . Évalué à 4.

        Quitte à utiliser un shell intelligent, autant se passer aussi de basename.

        name=${${PWD:t}// /_}

        Et pas besoin des guillemets puisque personne n'a le temps de les interpréter comme des séparateurs d'arguments.
        • [^] # Re: Re:

          Posté par  . Évalué à 1.

          Je ne connaissais pas, merci pour l'astuce. Par contre, il semble que ça fonctionne avec zsh mais pas avec bash.
      • [^] # Re: Re:

        Posté par  . Évalué à 1.

        Je me suis trompé, j'ai mis des {} au lieu de (). normalement, c'est

        cd "/home/sacha/Bureau/images/test image 2"
        name=$(basename "$(pwd)")
        name=${name// /_}
        echo $name
        => test_image_2
    • [^] # Re: Re:

      Posté par  . Évalué à -2.

      Le problème pourra venir des espaces dans les noms de dossier. Utilise les guillements
      basename "$(pwd)"

      Pour remplacer les espaces par des underscores, plutôt que sed et awk, le plus pratique, c'est d'utiliser les fonctions de remplacement du shell
      ${variable// /_}

      Au final, ça donne
      cd "/home/sacha/Bureau/images/test image 2"
      name=${basename "$(pwd)"}
      name=${name// /_}
      echo $name
      => test_image_2
    • [^] # Re: Re:

      Posté par  . Évalué à -2.

      Le problème pourra venir des espaces dans les noms de dossier. Utilise les guillements
      basename "$(pwd)"

      Pour remplacer les espaces par des underscores, plutôt que sed et awk, le plus pratique, c'est d'utiliser les fonctions de remplacement du shell
      ${variable// /_}

      Au final, ça donne
      cd "/home/sacha/Bureau/images/test image 2"
      name=${basename "$(pwd)"}
      name=${name// /_}
      echo $name

      ça donne test_image_2
      • [^] # Re: Re:

        Posté par  . Évalué à 1.

        C'est balot, ma page ne s'est pas rafraîchie et j'ai cru que le commentaire n'avait pas été posté
  • # suite

    Posté par  . Évalué à 1.

    merci à vous et notamment à christophe.

    mais moi j'ai un créer un scriptnew.sh

    cd "/home/sacha/Bureau/image test"
    name=${basename "$(pwd)"}
    name=${name// /_}
    echo $name




    et ca me donne:

    [sacha@localhost ~/Bureau/image test]$ scriptnew.sh
    /bin/scriptnew.sh: line 2: ${basename "$(pwd)"}: bad substitution


    et si j'essaye

    cd "/home/sacha/Bureau/image test"
    name=$(basename $(pwd))
    name=${name// /_}
    echo $name

    ca me donne:
    [sacha@localhost ~/Bureau/image test]$ scriptnew.sh
    image


    avec:
    name=basename "$(pwd)"
    ==> /bin/scriptnew.sh: line 2: /home/sacha/Bureau/image test: is a directory

    name=basename $(pwd)
    ==>/bin/scriptnew.sh: line 2: /home/sacha/Bureau/image: Aucun fichier ou répertoire de ce type


    du coup je suis un peu perdu?
    • [^] # Re: suite

      Posté par  . Évalué à 1.

      Et si tu essai avec:

      name="$(basename "$(pwd)")"
      • [^] # Re: suite

        Posté par  . Évalué à 1.

        C'est bon...

        Merci

        # Nom du nouveau répertoire
        NV_DOSSIER=reduc

        # Création du nouveau dossier s'il n'existe pas
        if [ -d $NV_DOSSIER ] ;
        then
        echo "Le dossier reduc existe déjà"
        else
        mkdir $NV_DOSSIER
        fi

        # Pour toutes les photos (JPG) du répertoire
        for i in *.[jJ][pP][gG] ;
        do
        # Réduit l'image en 601x400
        convert "$i" -resize 601x400 "$NV_DOSSIER/$i"
        # fusione l'image avec un calque contenant les coins
        composite -gravity center /home/sacha/Bureau/cadre.png "$NV_DOSSIER/$i" "$NV_DOSSIER/$i"
        # fin de la boucle FOR
        done
        rep=$(pwd)
        cd "$NV_DOSSIER"
        # mise a zero (1) du compteur
        num=1
        jourmois=$(date +'%d%m')

        for image in "$rep"/*[jJ][pP][gG]; do
        ((++num))
        rep="${image%/*}"
        rep="${rep##*/}"
        rep="${rep// /_}"
        image="${image##*/}"
        nv_nom=$(printf '%s_%s_%.4d_%s\n' ${rep} ${jourmois} ${num} $image) #on dit merci à Fred
        mv "$image" $nv_nom
        done
        • [^] # Re: suite

          Posté par  . Évalué à 2.

          y a plus qu'a optimiser pour ne pas faire 2 boucles mais une seule...
          • [^] # Re: suite

            Posté par  . Évalué à 1.

            Effectivement.

            D'autant plus que j'ai deux type d'image
            produit/producteur
            avec des tailles différentes, et des noms différents
            Du coup, pour l'instant ca me fais 4 boucles... et c'est horriblement long.

            Mais j'y travaille et je vous présente celà dès que j'ai fini.

            Merci à vous.
          • [^] # Re: suite

            Posté par  . Évalué à 2.

            et voiçi ma nouvelle version:

            # Nom du nouveau répertoire
            NV_DOSSIER=reduc

            # Création du nouveau dossier s'il n'existe pas
            if [ -d $NV_DOSSIER ] ;
            then
            echo "Le dossier reduc existe déjà"
            else
            mkdir $NV_DOSSIER
            fi
            rep=$(pwd)
            num=1
            jourmois=$(date +'%d%m')

            # Pour toutes les photos produit (JPG) du répertoire nommé 1.JPG,2.JPG....
            for image in [123456789].[jJ][pP][gG] ;
            do
            ((++num))
            # rep="${image%/*}"
            rep="${rep##*/}"
            rep="${rep// /-}"
            image="${image##*/}"
            nv_nom=$(printf '%s_%s_%s\n' ${rep} ${jourmois} $image) #on dit merci à Fred

            # Réduit l'image en 601x400
            convert "$image" -resize 601x400 "$NV_DOSSIER/$nv_nom"
            # fusione l'image avec un calque contenant les coins
            composite -gravity center /home/sacha/Bureau/cadre.png "$NV_DOSSIER/$nv_nom" "$NV_DOSSIER/$nv_nom"
            # fin de la boucle FOR
            done

            # Pour toutes les photos producteur (JPG) du répertoire nommé prod.JPG
            rep=$(pwd)
            image=''
            nv_nom=''
            for image in prod.[jJ][pP][gG] ;
            do
            ((++num))
            # rep="${image%/*}"
            rep="${rep##*/}"
            rep="${rep// /-}"
            image="${image##*/}"
            nv_nom=$(printf 'thai_prod_%s_%s.jpg\n' ${rep} ${jourmois}) #on dit merci à Fred

            # Réduit l'image en 601x400
            convert "$image" -resize 200x150 "$NV_DOSSIER/$nv_nom"
            # fusione l'image avec un calque contenant les coins
            composite -gravity center /home/sacha/Bureau/cadremini.png "$NV_DOSSIER/$nv_nom" "$NV_DOSSIER/$nv_nom"
            # fin de la boucle FOR
            done


            J'ai réussit a faire les deux boucles en une.
            cependant j'en ai rajouter une, car j'ai deux type d'image
            1- produit 1.JPG, 2.JPG 2816x1880px
            2-producteur prod.JPG 2272x1704px

            et que la 1- est réduite en 601x400
            et la 2 en 200x150

            cependant au lieu de tester par le nom de l'image serait il possible de tester par le ration d'image?


            MERCI ENCORE A VOUS TOUS
            • [^] # Re: suite

              Posté par  . Évalué à 1.

              bon je crois être sur la bonne piste.
              j'ai trouver la fonction identify
              qui permet de récupérer l'information que l'on veux sur un fichier

              j'ai donc fais:


              identify -format '%w' $image $width
              identify -format '%h' $image $height
              ratio=$(($width / $height))

              if [ratio...


              mais à chaque fois il me renvoie bien le résultat des identify mais les variable width et height reste vite.

              j'arrive pas à trouver la bonne syntaxe.
              • [^] # Re: suite

                Posté par  . Évalué à 1.

                bon j'ai avancé:

                width=$(identify -format '%w' "$image")
                height=$(identify -format '%h' "$image")
                ratio=$(($width / $height))
                echo $ratio

                if [ $ratio -gt 0.7 ]


                mais j'arrive pas à faire la division avec décimal. il me renvoie toujours $ratio

                et pour le if il me dis:

                /bin/reduc.sh: line 24: [: 0.7: integer expression expected


                Merci à vous
                • [^] # FINI!!!!

                  Posté par  . Évalué à 2.

                  ET VOILA!!!


                  # Nom du nouveau répertoire
                  NV_DOSSIER=reduc

                  # Création du nouveau dossier s'il n'existe pas
                  if [ -d $NV_DOSSIER ] ;
                  then
                  echo "Le dossier reduc existe déjà"
                  else
                  mkdir $NV_DOSSIER
                  fi
                  rep=$(pwd)
                  jourmois=$(date +'%d%m')

                  # Pour toutes les photos (JPG) du répertoire
                  for image in *[jJ][pP][gG] ;
                  do
                  rep="${rep##*/}"
                  rep="${rep// /-}"
                  width=$(identify -format '%w' "$image")
                  height=$(identify -format '%h' "$image")
                  ratio=$(echo "scale=2; $height / $width" |bc)
                  echo $ratio

                  if [ $ratio '<' .70 ]
                  then
                  image="${image##*/}"
                  nv_nom=$(printf '%s_%s_%s\n' ${rep} ${jourmois} $image) #on dit merci à Fred

                  # Réduit l'image en 601x400
                  convert "$image" -resize 601x400 "$NV_DOSSIER/$nv_nom"
                  # fusione l'image avec un calque contenant les coins
                  composite -gravity center /home/sacha/Bureau/cadre.png "$NV_DOSSIER/$nv_nom" "$NV_DOSSIER/$nv_nom"
                  # fin de la boucle FOR
                  else
                  nv_nom=$(printf 'thai_prod_%s_%s.jpg\n' ${rep} ${jourmois}) #on dit merci à Fred

                  # Réduit l'image en 601x400
                  convert "$image" -resize 200x150 "$NV_DOSSIER/$nv_nom"
                  # fusione l'image avec un calque contenant les coins
                  composite -gravity center /home/sacha/Bureau/cadremini.png "$NV_DOSSIER/$nv_nom" "$NV_DOSSIER/$nv_nom"
                  fi
                  done

        • [^] # Re: suite

          Posté par  . Évalué à 1.

          Dite moi j'ai chercher toute la journée mais j'arrive pas à trouver comment je pourrais rendre ce script sous kde.

          En clair que sous konqueror je fasse click droit sur le dossier, et qu'il me propose reduc
          et qu'il applique ce script sur ce dossier?

          Merci à vous
          • [^] # Re: suite

            Posté par  (Mastodon) . Évalué à 3.

            Sous kde, tu peux ajouter un "service menu" :
            Pose ton scrit où bon te semble (/usr/local/bin au hasard) puis créer un .desktop standart, ex :
            [Desktop Entry]
            Type=Service
            X-KDE-ServiceTypes=KonqPopupMenu/Plugin,inode/directory
            Actions=mon_action;

            [Desktop Action rmtilde]
            Name=my_action
            Name[fr]=mon_action
            icon=mon_icon
            Exec=/usr/local/bin/mon_action

            Tu déposes ce "mon_action.desktop" dans /usr/share/kde4/services/ServiceMenu/

            Sous Gnome, tu devra installer le paquet additionnel "nautilus-action" pour faire cela, et tu aura une interface graphique pour ajouter ton menu (inconvénient : ne sera pas disponible à tout utilisateur. Et deuxième inconvénient : on ne comprends pas vraiment illico ce qu'on fait... mieux vaut la méthode kde :p)
            • [^] # Re: suite

              Posté par  . Évalué à 1.

              Je te remercie, mais le souci c'est que je suis sous KDE3.5.

              Du coup j'ai pas de dossier /usr/share/kde

              J'ai essayer de le mettre sous
              ~/.kde/share/services/
              puis j'ai crée un dossier ServiceMenu mais ca semble pas fonctionner...

              Merci encore
              • [^] # servicemenu sous kde 3.5

                Posté par  . Évalué à 1.

                j'ai fini par trouver les service menu sous kde3.5 pour konqueror

                /usr/share/apps/konqueror/servicemenus/

                j'ai crée un service menu du type:

                [Desktop Entry]
                ServiceTypes=inode/directory
                Actions=reduc_imagecata;

                [Desktop Action reduc_imagecata]
                Name=reduc
                Name[fr]=reduc
                Icon=ark
                Exec=reduc.sh


                Il apparait bien sous konqueror, mais il ne s'execute pas.
                J'ai donc tester en lancant konqueror via la console, pour voir les eventuelle message d'erreur et là ca fonctionne.

                Vous auriez une idée pourquoi mon script ne fonctionne qu'a partir konqueror lancer via une console?

                Merci à vous

Suivre le flux des commentaires

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