Un problème avec les noms récursifs est que, quelle que soit la méthode utilisée pour localiser les fichiers, elle passe le chemin d'accès complet à rename
, pas seulement au nom du fichier. Cela rend difficile de faire des noms complexes dans les dossiers imbriqués.
J'utilise l’action find
de -execdir
pour résoudre ce problème. Si vous utilisez -execdir
au lieu de -exec
, la commande spécifiée est exécutée à partir du sous-répertoire contenant le fichier correspondant. Donc, au lieu de passer le chemin entier à rename
, il ne transmet que ./filename
. Cela facilite grandement l’écriture de la regex.
find /the/path -type f \
-name '*.abc' \
-execdir rename 's/\.\/(.+)\.abc$/version1_.abc/' '{}' \;
En détail:
-
-type f
signifie seulement rechercher les fichiers, pas les répertoires
-
-name '*.abc'
signifie que seuls les noms de fichiers qui se terminent par .abc correspondent à
- Les barres obliques inverses après
-type
et -name
sont le caractère de continuation de ligne bash. Je les utilise pour rendre cet exemple plus lisible, mais ils ne sont pas nécessaires dans la pratique.
- Cependant, la barre oblique inverse à la fin de la ligne
-execdir
est requise. Il est là pour esacpe le point-virgule, qui termine la commande exécutée par -execdir
. Fun!
Explication de l'expression rationnelle:
-
s/
start du regex
-
\.\/
correspond au premier ./ que -execdir passe. Utilisez \ pour échapper au. et / metacharacters
-
(.+)
correspond au nom du fichier. Les parenthèses capturent la correspondance pour une utilisation ultérieure
-
\.abc
échappe au point, correspond à l'abc
-
$
ancre la correspondance à la fin de la chaîne
-
/
marque la fin de la partie "match" de l'expression rationnelle et le début de la partie "replace"
-
version1_
ajoute ce texte à chaque nom de fichier
-
référence le nom de fichier existant, car nous l'avons capturé avec des parenthèses. Si vous utilisez plusieurs jeux de parenthèses dans la partie "match", vous pouvez vous y référer en utilisant $ 2, $ 3, etc.
-
.abc
le nouveau nom de fichier se terminera par .abc. Nul besoin d'échapper au métacaractère point dans la section "remplacer"
-
/
end du regex
Avant
tree --charset=ascii
|-- a_file.abc
|-- Another.abc
|-- Not_this.def
'-- dir1
'-- nested_file.abc
Après
tree --charset=ascii
|-- version1_a_file.abc
|-- version1_Another.abc
|-- Not_this.def
'-- dir1
'-- version1_nested_file.abc
Indice: L'option -n de rename
est utile. Il fait un essai à sec et vous indique quels noms il va changer, mais ne fait aucun changement.