Comment renommer tous les fichiers d'un répertoire, de manière récursive, en changeant une extension de fichier pour une autre, en milliers de fichiers dans des milliers de sous-dossiers? Je vois beaucoup de commandes qui font presque ce que je veux, mais pas tout à fait.
find . -name "*.andnav" -exec rename .andnav .tile {} \;
syntax error at (eval 1) line 1, near "."
...
rename -nv 's/\.andnav$/\.tile/i' *.andnav
0.png.andnav renamed as 0.png.tile
Deviner
find . -name "*.andnav" -exec rename -v 's/\.andnav$/\.tile/i' {} \;
./0/0.png.andnav renamed as ./0/0.png.tile
./0/1.png.andnav renamed as ./0/1.png.tile
./1/0.png.andnav renamed as ./1/0.png.tile
./1/1.png.andnav renamed as ./1/1.png.tile
bien sûr, supprimez le -v quand vous le faites, sinon vous perdrez du temps à afficher tous les fichiers
Avec zsh:
autoload zmv
zmv -n '(**/)(*).andnav' '$1$2.tile'
Supprimez le -n
pour effectuer le changement de nom.
Quelque chose comme:
find . -name '*.andnav' -exec sh -c 'mv "$0" "${0%.andnav}.tile"' {} \;
J'ai trouvé cette méthode est plus facile et plus facile à lire:
find . -name "*.andnav" | rename "s/\.andnav$/.tile/"
Au moins sur les dérivées Ubuntu, renommer prend une liste de fichiers de STDIN si aucun n’est sur la ligne de commande. Et cela peut être testé facilement avec:
find . -name "*.andnav" | rename -vn "s/\.andnav$/.tile/"
jusqu'à ce que vous obteniez le droit.
Renommez les fichiers et les répertoires avec find -execdir | rename
Si vous voulez renommer les fichiers et les répertoires, pas simplement avec un suffixe, c'est un bon modèle:
PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
find . -depth -execdir rename 's/findme/replaceme/' '{}' \;
L'option awesome -execdir
insère un cd
dans le répertoire avant d'exécuter la commande rename
, contrairement à -exec
.
-depth
veille à ce que le changement de nom soit effectué en premier lieu sur les enfants, puis sur les parents, afin d'éviter d'éventuels problèmes avec des répertoires parent manquants.
-execdir
est requis car le changement de nom ne fonctionne pas correctement avec les chemins d'entrée autres que les noms de base, par exemple. les échecs suivants:
rename 's/findme/replaceme/g' acc/acc
Le piratage PATH
est requis car -execdir
a un inconvénient très gênant: find
est extrêmement avisé et refuse de faire quoi que ce soit avec -execdir
si vous avez des chemins relatifs dans votre variable d'environnement PATH
, par exemple. ./node_modules/.bin
, échouant avec:
find: Le chemin relatif ‘./node_modules/.bin’ est inclus dans la variable d’environnement PATH, qui n’est pas sécurisée en combinaison avec l’action -execdir de find. Veuillez supprimer cette entrée de $ PATH
-execdir
est un GNU find extension to POSIX . rename
est basé sur Perl et provient du package rename
. Testé sous Ubuntu 18.10.
Renommer la solution de contournement de lookahead
Si vos chemins d'entrée ne proviennent pas de find
, ou si vous en avez assez du désagrément relatif des chemins, nous pouvons utiliser un préfixe Perl pour renommer en toute sécurité les répertoires comme suit:
git ls-files | sort -r | xargs rename 's/findme(?!.*\/)\/?$/replaceme/g' '{}'
Je n'ai pas trouvé d'analogue pratique pour -execdir
avec xargs
: Xargs: change le répertoire de travail en chemin du fichier avant de l'exécuter?
Le sort -r
est requis pour garantir que les fichiers viennent après leurs répertoires respectifs, car les chemins les plus longs suivent les plus courts avec le même préfixe.