Comment remplacer un caractère par un autre dans tous les noms de fichiers des répertoires actuels?

41

Comment renommer tous les fichiers / sous-répertoires du dossier actuel?

Disons que j'ai beaucoup de fichiers et de sous-répertoires contenant des espaces et que je souhaite remplacer tous les espaces par un trait de soulignement.

File 1
File 2
File 3
Dir 1
Dir 3

devrait être renommé en

File_1
File_2
File_3
Dir_1
Dir_3
NobbZ
la source

Réponses:

36

Si vous devez également renommer des fichiers de sous-répertoires et si votre findprédécesseur est pris en charge -execdir, vous pouvez le faire.

find /search/path -depth -name '* *' \
    -execdir bash -c 'mv -- "$1" "${1// /_}"' bash {} \;

Merci à @glenn jackman pour avoir suggéré une -depthoption findet pour me faire réfléchir.

Notez que sur certains systèmes (y compris ceux de GNU / Linux), il findpeut arriver que les fichiers dont le nom contient des espaces ainsi que des séquences d'octets ne formant pas des caractères valides ne soient pas détectés différent de la locale). Définir les paramètres régionaux sur C(comme dans LC_ALL=C find...) résoudrait le problème.

enzotib
la source
Vous devrez utiliser find -maxdepth 1pour faire exactement ce que le PO vous a demandé sur le fonctionnement du dossier actuel.
Caleb
1
Utilisez l’ -depthoption find et vous pourrez vous en débarrasser sort.
Glenn Jackman
@ glenn jackman: merci, je comprends maintenant que ma solution était fausse.
enzotib
2
Changement -name '* *'de -name '*_*'et le changement "${1// /_}"à"${1//_/.}"
enzotib
1
@ kroiz: cela s'appelle "substitution de modèle". Vous pouvez le trouver dans bashla page de manuel de.
enzotib
34

Dans n'importe quel shell, vous pouvez parcourir les fichiers dont le nom contient un espace. Remplacer les espaces par des traits de soulignement est facile dans bash, ksh et zsh avec la ${VARIABLE//PATTERN/REPLACEMENT}construction.

for x in *" "*; do
  mv -- "$x" "${x// /_}"
done

Sur Debian, Ubuntu et ses dérivés, vous pouvez utiliser Perl rename(les autres distributions livrent un programme différent en tant que rename, et ce programme n’est pas utile ici).

rename 's/ /_/g' *

Une solution zsh obligatoire:

autoload zmv
zmv '(*)' '${1// /_}'

Une solution POSIX obligatoire:

for x in *" "*; do
  y=$(printf %sa "$x" | tr " " "_")
  mv -- "$x" "${y%a}"
done
Gilles, arrête de faire le mal
la source
Que signifie le "g" à la fin de la commande "renommer"? Je ne l'ai pas vu dans le manuel.
JulianLai
Comment renommer le répertoire seulement? Je ne veux pas changer le nom du fichier.
JulianLai
@ JulianLai s/…/…/gsignifie remplacer toutes les occurrences. Ce n'est pas très bien expliqué dans le manuel . Si vous souhaitez renommer des répertoires, vous pouvez le rechercher (je pense l'avoir déjà vu auparavant) et, si vous ne le trouvez pas, posez une nouvelle question.
Gilles, arrête de faire le mal
grande ... cela m'a aidé à renommer tous _MG_blah.JPGà IMG_blah.JPG.
Abinash Dash
13

Vous pouvez utiliser renamepour cela (en supposant ici celui de util-linux, pas perlcelui):

cd /path/to/dir
rename ' ' _ *\ *

Cela trouvera tous les espaces et répertoires dans le nom et remplacera l’espace par un trait de soulignement. Comme il utilise la correspondance de fichier glob, vous devez être dans le bon répertoire pour commencer.

Si vous voulez faire des correspondances récursives, vous pouvez, mais vous devrez peut-être exécuter renameplusieurs fois pour attraper tous les éléments des répertoires qui ont eux-mêmes été renommés:

cd /path/to/dir
shopt -s globstar
rename ' ' _ **/*\ *
!!; !!
Caleb
la source
2
renameRenommera les fichiers spécifiés en remplaçant le première apparition de partir en leur nom par la . » Donc , cela ne fonctionnera que pour les fichiers avec un seul espace dans leur nom. (Vous pouvez appeler renameen boucle, mais ce n'est pas vraiment le bon outil ici.)
Gilles 'SO, arrête de faire le mal'
2

Une autre option serait mmv, si installé.

mmv \*\ \* \#1_#2
glglgl
la source
Cela ne change que le premier espace en a _, cela ne fonctionne pas avec les noms comportant plusieurs espaces.
Gilles, arrête de faire le mal
Oups, vous avez raison. Désolé pour la confusion.
Glglgl
1

Sur Debian / Ubuntu, en s’appuyant sur les réponses de Caleb et Gilles, c’est ce qui a fonctionné pour moi pour renommer les fichiers de manière récursive:

cd /path/to/dir
shopt -s globstar
rename 's/ /_/g' **

Remarque: pour prévisualiser quels fichiers seront renommés et comment, utilisez le -ncommutateur avec rename:

rename -n 's/ /_/g' **

Autre remarque: ce paramètre globstarpermet de faire **correspondre les fichiers de tous les sous-répertoires. Par conséquent, si vous souhaitez uniquement utiliser le répertoire actuel, ne définissez pas globstar ni utilisez-le à la *place de **.

Remarque supplémentaire: la renamecommande doit être exécutée plusieurs fois pour les fichiers contenant plusieurs occurrences du terme recherché.

Markus Pscheidt
la source
Cela ne fonctionne que si les répertoires ne contiennent pas d'espaces. (un changement de nom de a b/c dà a_b/c_dne travaillerait, vous aurez besoin d' abord renommer a b/c dà a b/c_d, puis a bà a_b).
Stéphane Chazelas
@ Stéphane: Est-ce que cela signifie exécuter la même renamecommande deux fois?
Markus Pscheidt
Eh bien, plus souvent, il y a des niveaux imbriqués de répertoires avec des espaces. Idéalement, vous souhaitez traverser d'abord la profondeur du répertoire et convertir uniquement le nom de base du fichier, comme dans la solution acceptée. Notez également que bash **exclut les fichiers de points et traverse les liens symboliques.
Stéphane Chazelas
0

Si vous n’êtes pas un flash dans les expressions régulières (ce n’est pas le cas!) Et que vous pouvez exécuter des applications conçues pour kde (que vous utilisiez kde-k desktop ou que vous ayez ses bibliothèques installées), alors krename est un excellent utilitaire graphique vous permet de voir l'avant et l'après avant de vous engager dans les modifications. Il comporte un certain nombre de transformations simples en tant qu'options et prend également en charge les expressions régulières. Vous pouvez même combiner plusieurs transformations séquentielles en un seul renommage afin de ne pas avoir à concevoir une seule transformation complexe qui le fasse tous en même temps. Il a également une option pour continuer à renommer les mêmes fichiers après qu’un changement de nom ait été appliqué.

Je ne l'utilise pas souvent, mais quand je l'utilise, le travail est fait rapidement et facilement. Il est très pratique lorsque vous renommez divers fichiers multimédias téléchargés afin que vous puissiez les gérer de manière uniforme sur votre système. Il est utile de télécharger le manuel de krename séparément afin que vous puissiez vous y reporter lorsque vous utilisez le programme.

http://www.krename.net/

Joe
la source