web-dev-qa-db-fra.com

Renommer des fichiers en ajoutant le suffixe "cyclisme"

J'ai un répertoire contenant des sous-répertoires contenant de nombreux fichiers nommés comme:

file1.tif
file2.tif
file3.tif
file4.tif
file5.tif
file6.tif
file7.tif...

Je veux ajouter un suffixe "cyclique" c1, c2 et c3, pour obtenir les noms de fichier:

file1c1.tif
file2c2.tif
file3c3.tif
file4c1.tif
file5c2.tif
file6c3.tif
file7c1.tif...

Et ceci dans tous les sous-répertoires du répertoire principal.

Mais je ne peux pas savoir comment faire ça.

Est-ce possible? Comment?

5
Philippe P

Avec find + le prename basé sur Perl (alias rename sur une version antérieure d'Ubuntus), vous pouvez faire correspondre la séquence de chiffres précédant un . littéral, puis l'écrire au format souhaité. en utilisant la division modulo, par exemple.

find . -name '*.tif' -execdir prename -vn -- 's/(\d+)\./sprintf "%dc%d.", $1, ($1-1)%3+1/e' {} +

(Les drapeaux -vn vous permettent de faire un "essai à blanc" pour voir comment les fichiers seraient renommés avant d'être validés).


Ex. donné

$ tree
.
├── bar
│   ├── file1.tif
│   ├── file2.tif
│   ├── file3.tif
│   ├── file4.tif
│   ├── file5.tif
│   ├── file6.tif
│   └── file7.tif
├── foo
│   ├── Egg
│   │   ├── file1.tif
│   │   └── file2.tif
│   ├── file1.tif
│   ├── file2.tif
│   └── file3.tif
└── spam
    ├── file1.tif
    └── file2.tif

4 directories, 14 files

Ensuite

find . -name '*.tif' -execdir prename -- 's/(\d+)\./sprintf "%dc%d.", $1, ($1-1)%3+1/e' {} +

résulte en

$ tree
.
├── bar
│   ├── file1c1.tif
│   ├── file2c2.tif
│   ├── file3c3.tif
│   ├── file4c1.tif
│   ├── file5c2.tif
│   ├── file6c3.tif
│   └── file7c1.tif
├── foo
│   ├── Egg
│   │   ├── file1c1.tif
│   │   └── file2c2.tif
│   ├── file1c1.tif
│   ├── file2c2.tif
│   └── file3c3.tif
└── spam
    ├── file1c1.tif
    └── file2c2.tif

4 directories, 14 files
7
steeldriver

Editer basé sur le commentaire:

Si vous souhaitez faire défiler le compteur, c'est-à-dire <number> dans c<number>, faites un cycle entre 1 et 3:

Passage à sec:

shopt -s globstar
for d in **/*/; do 
    ( cd "$d" && pwd && count=1 && shopt -s nullglob && for f in file*.tif; do 
        echo mv -i "$f" "${f%.tif}"c${count}.tif
        if ((count=3)); then 
            count=1
        else
            ((count++))
        fi
     done ) 
done

Action:

shopt -s globstar
for d in **/*/; do 
    ( cd "$d" && count=1 && shopt -s nullglob && for f in file*.tif; do 
        mv -i "$f" "${f%.tif}"c${count}.tif
        if ((count=3)); then 
            count=1
        else
            ((count++))
        fi
     done ) 
done

Exemple:

$ tree
.
├── bar
│   ├── file1.tif
│   ├── file2.tif
│   ├── file3.tif
│   └── file4.tif
├── foo
│   ├── Egg
│   │   ├── file1.tif
│   │   └── file2.tif
│   ├── file1.tif
│   ├── file2.tif
│   └── file3.tif
└── spam
    ├── file1.tif
    └── file2.tif

$ shopt -s globstar
$ for d in **/*/; do ( cd "$d" && pwd && count=1 && shopt -s nullglob && for f in file*.tif; do \
    echo mv -i "$f" "${f%.tif}"c${count}.tif; if ((count=3)); then count=1; else ((count++)); fi; done ); done
/home/foobar/bar
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
mv -i file3.tif file3c3.tif
mv -i file4.tif file4c1.tif
/home/foobar/foo
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
mv -i file3.tif file3c3.tif
/home/foobar/foo/Egg
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
/home/foobar/spam
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif

$ for d in **/*/; do ( cd "$d" && count=1 && shopt -s nullglob && for f in file*.tif; do \
    mv -i "$f" "${f%.tif}"c${count}.tif; if ((count=3)); then count=1; else ((count++)); fi; done ); done

$ tree
.
├── bar
│   ├── file1c1.tif
│   ├── file2c2.tif
│   ├── file3c3.tif
│   └── file4c1.tif
├── foo
│   ├── Egg
│   │   ├── file1c1.tif
│   │   └── file2c2.tif
│   ├── file1c1.tif
│   ├── file2c2.tif
│   └── file3c3.tif
└── spam
    ├── file1c1.tif
    └── file2c2.tif

Réponse originale:

Avec bash:

shopt -s globstar
for d in **/*/; do ( cd "$d" && pwd && count=1 && shopt -s nullglob \
    && for f in file*.tif; do echo mv -i "$f" "${f%.tif}"c${count}.tif; \
        ((count++)); done ); done
  • Ici, nous parcourons les noms de répertoires, l'option globstar Shell nous permet de parcourir les répertoires de manière récursive

  • La partie à l'intérieur de () s'exécute dans un sous-shell afin d'empêcher la modification de cd dans le shell en cours.

  • Nous sommes cd- dans les répertoires, recherchant les fichiers file*.tif et les renommant au besoin

  • conserver un compteur incrémentant, count, pour chaque fichier en renommant


La procédure ci-dessus est exécutée à sec. Elle indique le répertoire dans lequel le changement de nom sera effectué et la commande mv à exécuter. Si satisfait, faites:

shopt -s globstar
for d in **/*/; do ( cd "$d" && count=1 && shopt -s nullglob && \
  for f in file*.tif; do mv -i "$f" "${f%.tif}"c${count}.tif; ((count++)); done ); done

Il y a une mise en garde, à savoir que Shell procède au tri lexical pour les fichiers, par exemple. file10.tif sera renommé avant file2.tif. Si vous ne le souhaitez pas, effectuez un tri avant de renommer ou utilisez zsh avec l'option numericglobsort.

6
heemayl

Grâce à Heemayl, tout a été réglé. Nous avons dû modifier un peu la boucle d’incrément de cycle indiquée, car elle ne fonctionnait pas entre nos mains. Nous avons changé: if ((count = 3)) en: if (("$ count" == 3)) Le code final que nous utilisons avec succès est le suivant:

    shopt -s globstar
for d in **/*/; do 
    ( cd "$d" && count=1 && shopt -s nullglob && for f in *.tif; do 
       echo mv -i "$f" "${f%.tif}"c${count}.tif

if (("$count"==3)); then 
count=1
        else 
((count++))
        fi
     done ) 
done

Merci encore à heemayl pour son aide et sa patience ...

0
Philippe P