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?
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
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
.
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 ...