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!' {} +