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