find ./* -depth -type d -exec sh -c ' ... ' {} \;
find s todos os diretórios ( -type d ) na árvore e executa esse fragmento de shell para cada um deles, com $0 definido para o nome atual. -depth faz com que processe o conteúdo de cada diretório primeiro e o diretório em si. (caso contrário, a renomeação estraga as coisas.)
t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
${0%/*} remove a última barra e tudo depois dela de $0 , ou seja, deixa o nome do diretório. ${0##*/} é basicamente o oposto. (Eles são tipos de expansão de parâmetro ) O printf | tr é usado para alterar a parte final do nome para minúsculas. O resultado é atribuído a t . ( $(...) é substituição de comando )
[ "$t" = "$0" ] || mv -i "$0" "$t"
Tests para ver se o novo nome em t e o nome antigo em $0 são os mesmos, e se não , chama mv neles.
As partes tolas aqui são que find poderia ser chamado apenas de find . -depth ... , não há necessidade do caractere curinga de nome de arquivo ( find ./* ), pois localizar os nomes dos arquivos é o que find faz. Se eles usassem -execdir em vez de -exec , não haveria necessidade de lidar com a parte do diretório dos nomes dos arquivos. E usar $0 para o nome do arquivo de destino é um pouco ruim, é para o nome do próprio script.
Você mencionou renomear arquivos e diretórios e alterar o espaço em branco para traços. Tanto quanto eu posso ver, o comando aqui não faz nenhum. find -type d apenas pega diretórios, você precisaria usar -type f para capturar apenas arquivos regulares ou deixá-los de fora para ignorar o tipo. Além disso, não há nada sobre o espaço em branco no tr , mas você pode alterá-lo para, digamos, tr "[:upper:][:space:]" "[:lower:][-*]" para também alterar todos os espaços em branco para traços.