233 votes

Comment renommer tous les dossiers et fichiers en minuscules sous Linux ?

Je dois renommer une arborescence complète de dossiers de manière récursive afin qu'aucune lettre majuscule n'apparaisse nulle part (il s'agit d'un code source C++, mais cela ne devrait pas avoir d'importance).

Points bonus pour avoir ignoré les fichiers/dossiers de contrôle de version CVS et Subversion. Le moyen préféré serait un shell script, puisqu'un shell devrait être disponible sur toute boîte Linux.

Il y a eu quelques arguments valables concernant les détails du renommage des fichiers.

  1. Je pense que les fichiers ayant les mêmes noms en minuscules devraient être écrasés ; c'est le problème de l'utilisateur. Lorsqu'il est extrait sur un système de fichiers ignorant la casse, il écrase le premier fichier avec le second également.

  2. Je prendrais en compte les caractères A-Z et les transformerais en a-z, tout le reste n'est que source de problèmes (du moins avec le code source).

  3. Le script serait nécessaire pour exécuter un build sur un système Linux, donc je pense que les modifications des fichiers de contrôle de version CVS ou Subversion devraient être omises. Après tout, c'est juste un "scratch checkout". Peut-être qu'une "exportation" est plus appropriée.

0 votes

La méthode affichée précédemment fonctionnera parfaitement ou avec quelques ajustements pour les cas simples, mais il y a certaines situations que vous voudrez peut-être prendre en compte avant d'exécuter le renommage par lot : 1. Que se passe-t-il si vous avez deux ou plusieurs noms au même niveau dans la hiérarchie des chemins qui ne diffèrent que par la casse, tels que ABCdef , abcDEF y aBcDeF ? Le renommage script doit-il avorter ou simplement avertir et continuer ? 2. Comment définir les minuscules pour les noms non US-ASCII ? Si de tels noms peuvent être présents, faut-il effectuer d'abord une passe de vérification et d'exclusion ? 3. Si vous exécutez une opération de renommage

314voto

tristanbailey Points 940

Plus petit encore, j'aime bien :

rename 'y/A-Z/a-z/' *

Sur les systèmes de fichiers insensibles à la casse, comme le système OS X HFS+ vous devez ajouter l'élément -f drapeau :

rename -f 'y/A-Z/a-z/' *

3 votes

linux.icydog.net/rename.php : The renaming utility that comes by default with Ubuntu is a Perl program sometimes called prename

2 votes

Merci, je l'ai utilisé de cette façon $ find | xargs rename 'y/A-Z/a-z/' *

0 votes

Hmm... J'obtiens "./ABC.txt" non renommé. './abc.txt' existe déjà" même si ce n'est pas le cas.

197voto

Alex B Points 34304

Une version concise utilisant le "rename" commandement :

find my_root_dir -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;

Cela permet d'éviter les problèmes liés aux répertoires renommés avant les fichiers et d'essayer de déplacer des fichiers dans des répertoires inexistants (par ex. "A/A" en "a/a" ).

Ou, une version plus verbeuse sans utiliser "rename" .

for SRC in `find my_root_dir -depth`
do
    DST=`dirname "${SRC}"`/`basename "${SRC}" | tr '[A-Z]' '[a-z]'`
    if [ "${SRC}" != "${DST}" ]
    then
        [ ! -e "${DST}" ] && mv -T "${SRC}" "${DST}" || echo "${SRC} was not renamed"
    fi
done

P.S.

Cette dernière permet une plus grande flexibilité avec la commande de déplacement (par exemple, "svn mv" ).

39 votes

L'utilisation de rename peut être faite de cette façon aussi rename 'y/A-Z/a-z/' *

5 votes

Attention, les deux versions ne fonctionneront pas sur un système de fichiers insensible à la casse. Dans mon cas, j'ai remplacé le then -ligne fermée par (mv "${SRC}" "${DST}.renametmp" && mv "${DST}.renametmp" "${DST}") || echo "${SRC} was not renamed" .

6 votes

La deuxième approche n'a pas fonctionné correctement pour moi avec des fichiers contenant des espaces vides (contexte : linux, bash).

111voto

Swaroop C H Points 7518
for f in `find`; do mv -v "$f" "`echo $f | tr '[A-Z]' '[a-z]'`"; done

0 votes

Veuillez faire un "mkdir -p A/B/C" avant d'exécuter votre script.

2 votes

"find" doit être remplacé par la commande que vous utilisez pour obtenir une liste des fichiers que vous souhaitez renommer ; par exemple, "ls *.{C,CPP,H}".

0 votes

for f in *.txt; do mv -v $f echo $f | tr [:upper :] [:lower :] ; done Fonctionne avec des espaces sur debian.

16voto

niXar Points 569

La plupart des réponses ci-dessus sont dangereuses, car elles ne traitent pas les noms contenant des caractères impairs. La solution la plus sûre pour ce genre de choses est d'utiliser la fonction find 's -print0 qui terminera les noms de fichiers avec ASCII NUL au lieu de \n.

Voici un script, qui ne modifie que les fichiers et non les noms de répertoire pour ne pas confondre. find :

find .  -type f -print0 | xargs -0n 1 bash -c \
's=$(dirname "$0")/$(basename "$0");
d=$(dirname "$0")/$(basename "$0"|tr "[A-Z]" "[a-z]"); mv -f "$s" "$d"'

Je l'ai testé, et il fonctionne avec des noms de fichiers contenant des espaces, toutes sortes de guillemets, etc. Ceci est important car si vous exécutez, en tant que Root, l'un de ces autres scripts sur un arbre qui inclut le fichier créé par

touch \;\ echo\ hacker::0:0:hacker:\$\'\057\'root:\$\'\057\'bin\$\'\057\'bash

... et bien devinez quoi ...

0 votes

Il serait plus simple à utiliser rename au lieu de mv .

6voto

vividos Points 1933

Voici ma solution sous-optimale, utilisant un shell Bash script :

#!/bin/bash
# First, rename all folders
for f in `find . -depth ! -name CVS -type d`; do
   g=`dirname "$f"`/`basename "$f" | tr '[A-Z]' '[a-z]'`
   if [ "xxx$f" != "xxx$g" ]; then
      echo "Renaming folder $f"
      mv -f "$f" "$g"
   fi
done

# Now, rename all files
for f in `find . ! -type d`; do
   g=`dirname "$f"`/`basename "$f" | tr '[A-Z]' '[a-z]'`
   if [ "xxx$f" != "xxx$g" ]; then
      echo "Renaming file $f"
      mv -f "$f" "$g"
   fi
done

Les dossiers sont tous renommés correctement, et mv ne pose pas de questions lorsque les permissions ne correspondent pas, et les dossiers CVS ne sont pas renommés (les fichiers de contrôle CVS à l'intérieur de ce dossier sont toujours renommés, malheureusement).

Puisque "find -depth" et "find | sort -r" retournent tous deux la liste des dossiers dans un ordre utilisable pour le renommage, j'ai préféré utiliser "-depth" pour la recherche de dossiers.

0 votes

Votre première trouvaille ne fonctionne pas. Essayez "mkdir -p A/B/C" et ensuite exécutez votre script.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X