Je veux mettre en minuscules le nom de chaque répertoire sous un répertoire. Avec quelles commandes puis-je faire cela ?
Réponse acceptée :
Tous les répertoires à un niveau, ou récursivement ?
Zsh
À un niveau :
autoload zmv
zmv -o-i -Q 'root/(*)(/)' 'root/${1:l}'
Récursivement :
zmv -o-i -Q 'root/(**/)(*)(/)' 'root/$1${2:l}'
Explications :zmv
renomme les fichiers correspondant à un motif en fonction du texte de remplacement donné. -o-i
passe le -i
option à chaque mv
commande sous le capot (voir ci-dessous). Dans le texte de remplacement, $1
, $2
, etc, sont les groupes successifs entre parenthèses dans le motif. **
signifie tous les (sous)*répertoires, récursivement. Le dernier (/)
n'est pas un groupe entre parenthèses mais un qualificatif glob signifiant qu'il ne correspond qu'aux répertoires. ${2:l}
convertit $2
en minuscules.
Portable
À un niveau :
for x in root/*/; do mv -i "$x" "$(printf %s "$x" | tr '[:upper:]' '[:lower:]')"; done
Le dernier /
limite la correspondance aux répertoires et mv -i
le fait demander une confirmation en cas de collision. Supprimez le -i
pour écraser en cas de collision, et utilisez yes n | for …
. pour ne pas être invité et ne pas effectuer de changement de nom qui pourrait entrer en collision.
Récursivement :
find root/* -depth -type d -exec sh -c '
t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
[ "$t" = "$0" ] || mv -i "$0" "$t"
' {} ;
L'utilisation de -depth
garantit que les répertoires profondément imbriqués sont traités avant leurs ancêtres. Le traitement du nom repose sur la présence d'un /
; si vous voulez appeler opérer dans le répertoire courant, utilisez ./*
(adaptation du script shell pour faire face à .
ou *
est laissé en exercice au lecteur).
Renommer Perl
Ici, j'utilise le script de renommage Perl fourni par Debian et Ubuntu sous la forme /usr/bin/prename
(généralement disponible en tant que rename
aussi bien). À un niveau :
rename 's!/([^/]*/?)$!L/$1!' root/*/
Récursivement, avec bash ≥4 ou zsh :
shopt -s globstar # only in bash
rename 's!/([^/]*/?)$!L/$1!' root/**/*/
De manière récursive, portable :
find root -depth -type d -exec rename -n 's!/([^/]*/?)$!L/$1!' {} +