Quiero poner en minúsculas el nombre de cada directorio debajo de un directorio. ¿Con qué comandos puedo hacer eso?
Respuesta aceptada:
¿Todos los directorios en un nivel, o recursivamente?
Zsh
En un nivel:
autoload zmv
zmv -o-i -Q 'root/(*)(/)' 'root/${1:l}'
Recursivamente:
zmv -o-i -Q 'root/(**/)(*)(/)' 'root/$1${2:l}'
Explicaciones:zmv cambia el nombre de los archivos que coinciden con un patrón de acuerdo con el texto de reemplazo dado. -o-i pasa el -i opción para cada mv comando bajo el capó (ver más abajo). En el texto de reemplazo, $1 , $2 , etc., son los grupos sucesivos entre paréntesis en el patrón. ** significa todos los (sub)*directorios, recursivamente. El (/) final no es un grupo entre paréntesis sino un calificador global que significa que solo coincide con directorios. ${2:l} convierte $2 a minúsculas.
Portátil
En un nivel:
for x in root/*/; do mv -i "$x" "$(printf %s "$x" | tr '[:upper:]' '[:lower:]')"; done
El / final restringe la coincidencia de directorios y mv -i hace que pida confirmación en caso de colisión. Eliminar el -i para sobrescribir en caso de colisión, y use yes n | for … . para que no se le solicite y no realice ningún cambio de nombre que pueda colisionar.
Recursivamente:
find root/* -depth -type d -exec sh -c '
t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
[ "$t" = "$0" ] || mv -i "$0" "$t"
' {} ;
El uso de -depth asegura que los directorios profundamente anidados se procesen antes que sus ancestros. El procesamiento de nombres se basa en que haya un /; si desea llamar operar en el directorio actual, use ./* (adaptando el script de shell para hacer frente a . o * se deja como ejercicio para el lector).
Renombrar Perl
Aquí uso el script de cambio de nombre de Perl que Debian y Ubuntu envían como /usr/bin/prename (típicamente disponible como rename así como). En un nivel:
rename 's!/([^/]*/?)$!L/$1!' root/*/
De forma recursiva, con bash ≥4 o zsh:
shopt -s globstar # only in bash
rename 's!/([^/]*/?)$!L/$1!' root/**/*/
De forma recursiva, portable:
find root -depth -type d -exec rename -n 's!/([^/]*/?)$!L/$1!' {} +