Veja o que acontece:
-
find
encontra o diretório correspondente./Test 02
. -
find
executa o comandorename
nesse diretório. -
rename
renamesTest 02
paraTest_02
. -
find
tenta descer no diretórioTest 02
. Mas isso não existe mais.
A maneira mais fácil de resolver esse problema é dizer ao find
para trabalhar ao contrário: primeiro procure por correspondências dentro do diretório e, em seguida, verifique se o diretório em si corresponde. Isso é o que a opção -depth
faz.
Se você adicionar apenas -depth
, encontrará outro problema, que quando find
atingir Test 01/Test A
, invocará rename 'y/\ /\_/' 'Test 01/Test A'
, que tentará renomear esse diretório para Test_01/Test_A
. Isso falhará, pois não há diretório chamado Test_01
. Uma solução fácil é usar a opção -execdir
, que invoca rename
dentro do diretório Test 01
e passa Test A
como argumento. Você pode acelerar as coisas passando vários argumentos para rename
em um lote, usando +
em vez de ;
para finalizar o comando -execdir
.
find -depth -name '* *' -type d -execdir rename 'y/ /_/' {} +
Como alternativa, use este comando zsh curto, mas enigmático:
autoload zmv
zmv -Qw '**/*(/D)' '$1${2// /_}'
A zmv
function renomeia os arquivos de acordo com os padrões. O padrão de origem é **/*
, que corresponde a todos os arquivos ( *
) em todos os subdiretórios recursivamente ( **/
). Os qualificadores de glob (ativados pela opção -Q
) indicam que apenas diretórios são correspondidos ( /
) e que os arquivos de ponto estão incluídos ( D
). A opção -w
cria uma referência anterior para cada caractere curinga no padrão de origem. A substituição começa com $1
, que designa a correspondência para o primeiro caractere curinga (por **
, isso inclui um% final/
) e é seguido por ${2// /_}
, que é $2
(o que coincide *
) modificado para substituir todos os caracteres de espaço por _
. Adicione a opção -v
para ver o que o comando faz, você notará que ele percorre a profundidade primeiro como find -depth
.