Solução zig obrigatória:
for x in root/**/*(On); do mv -i $x ${x:h}/${x:t:l}; done
Isso pedirá confirmação em caso de colisão.
Explicação: **
significa todos os diretórios (sub) *, recursivamente. (On)
ordena a ordem lexicográfica decrescente, de modo que os diretórios sempre aparecem após o conteúdo. ${x:h}
significa que a parte do nome do diretório de $x
, ${x:t}
significa seu nome base e o :l
convertido para minúsculas.
O Bash 4 pode fazer isso, pois tem **
, mas não sei se tem um equivalente de (On)
.