Renommer récursivement des fichiers (modifier l'extension) sous Linux


22

Comment renommer tous les fichiers d'un répertoire, de manière récursive, en changeant une extension de fichier en une autre, pour des 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

1
Avez-vous Debian renameou Red Hat rename?
Ignacio Vazquez-Abrams

@Ignacio: Ubuntu = Debian?
endolith

Oui, Ubuntu est un dérivé de Debian.
Ignacio Vazquez-Abrams

Réponses:


23

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 lorsque vous le faites, ou cela perdra du temps à afficher tous les fichiers


14

Quelque chose comme:

find . -name '*.andnav' -exec sh -c 'mv "$0" "${0%.andnav}.tile"' {} \;

celui-ci a fonctionné le mieux pour moi
cwd


4

J'ai trouvé que cette méthode est de plus en plus facile à lire:

find . -name "*.andnav" | rename "s/\.andnav$/.tile/"

Au moins sur les dérivations 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 compreniez bien.


1

Renommez les fichiers et les répertoires avec find -execdir | rename

Si vous allez renommer à la fois des fichiers et des répertoires non pas simplement avec un suffixe, alors c'est un bon modèle:

PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
  find . -depth -execdir rename 's/findme/replaceme/' '{}' \;

Contrairement à, l' -execdiroption génial fait un cddans le répertoire avant d'exécuter la renamecommande -exec.

-depth assurez-vous que le changement de nom se produit d'abord sur les enfants, puis sur les parents, pour éviter les problèmes potentiels avec les répertoires parent manquants.

-execdir est requis car le changement de nom ne fonctionne pas bien avec les chemins d'entrée autres que les noms de base, par exemple ce qui suit échoue:

rename 's/findme/replaceme/g' acc/acc

Le PATHpiratage est nécessaire car il -execdira un inconvénient très ennuyeux: il findest extrêmement avisé et refuse de faire quoi que ce soit avec -execdirsi vous avez des chemins relatifs dans votre PATHvariable d'environnement, par exemple ./node_modules/.bin, en échouant avec:

find: Le chemin relatif './node_modules/.bin' est inclus dans la variable d'environnement PATH, qui n'est pas sécurisé en combinaison avec l'action -execdir de find. Veuillez supprimer cette entrée de $ PATH

Voir aussi: /ubuntu/621132/why-using-the-execdir-action-is-insecure-for-directory-which-is-in-the-path/1109378#1109378

-execdirest une extension GNU find pour POSIX . renameest basé sur Perl et provient du renamepackage. Testé dans Ubuntu 18.10.

Renommer la solution de contournement

Si vos chemins d'entrée ne proviennent pas find, ou si vous en avez assez de la gêne relative du chemin, nous pouvons utiliser une anticipation Perl pour renommer en toute sécurité les répertoires comme dans:

git ls-files | sort -r | xargs rename 's/findme(?!.*\/)\/?$/replaceme/g' '{}'

Je ne l' ai pas trouvé un analogue pratique pour -execdiravec xargs: xargs: répertoire de travail modification chemin du fichier avant d' exécuter?

Il sort -rest nécessaire de s'assurer que les fichiers viennent après leurs répertoires respectifs, car les chemins plus longs viennent après les plus courts avec le même préfixe.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.