Todos os diretórios em um nível ou recursivamente?
Zsh
Em um nível:
autoload zmv
zmv -o-i -Q 'root/(*)(/)' 'root/${1:l}'
Recursivamente:
zmv -o-i -Q 'root/(**/)(*)(/)' 'root/$1${2:l}'
Explicações: zmv
renomeia arquivos que correspondem a um padrão de acordo com o texto de substituição fornecido. -o-i
passa a opção -i
para cada comando mv
sob o capô (veja abaixo). No texto de substituição, $1
, $2
, etc, são os sucessivos grupos entre parênteses no padrão. **
significa todos os diretórios (sub) *, recursivamente. O% final (/)
não é um grupo entre parênteses, mas um qualificador glob que significa corresponder apenas aos diretórios. ${2:l}
converte $2
em minúsculas.
Portátil
Em um nível:
for x in root/*/; do mv -i "$x" "$(printf %s "$x" | tr '[:upper:]' '[:lower:]')"; done
O% final /
restringe a correspondência aos diretórios e mv -i
solicita confirmação em caso de colisão. Remova o -i
para sobrescrever no caso de uma colisão e use yes n | for …
. para não ser avisado e não executar qualquer renomeação que colidiria.
Recursivamente:
find root/* -depth -type d -exec sh -c '
t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
[ "$t" = "$0" ] || mv -i "$0" "$t"
' {} \;
O uso de -depth
garante que diretórios profundamente aninhados sejam processados antes de seus ancestrais. O processamento de nomes depende de haver um /
; Se você quiser chamar operar no diretório atual, use ./*
(adaptar o script de shell para lidar com .
ou *
é deixado como um exercício para o leitor).
Perl renomear
Aqui eu uso o script de renomeação Perl que o Debian e o Ubuntu enviam como /usr/bin/prename
(normalmente disponível como rename
também). Em um nível:
rename 's!/([^/]*/?)$!\L/$1!' root/*/
Recursivamente, com bash ≥4 ou zsh:
shopt -s globstar # only in bash
rename 's!/([^/]*/?)$!\L/$1!' root/**/*/
Recursivamente, portably:
find root -depth -type d -exec rename -n 's!/([^/]*/?)$!\L/$1!' {} +