O código que você postou renomeia arquivos e pastas. No entanto, ele não recursivamente renomeia arquivos e pastas dentro de pastas.
Dado que sua máscara DIR tem uma extensão e, como os nomes das pastas normalmente não têm extensões, acho que você simplesmente deseja renomear os arquivos, e não as pastas. Se esse for o caso, tudo o que você precisa é adicionar a opção DIR /S
para recursar nas pastas filhas e a opção /A-D
para excluir pastas. Você deve definir newname apenas para o nome do arquivo, desconsiderando o caminho, via %%nxF
. E o comando MOVE requer o caminho de destino de %%dpF
. Isso dará uma solução que normalmente funciona, embora possa haver complicações (mais sobre isso depois).
@echo off
setlocal enableDelayedExpansion
set "old=V1"
set "new=newdocV2"
for /f "delims=" %%F in ('dir /b /s /a-d *.ods') do (
set "newname=%%~nxF"
set "newname=!newname:%old%=%new%!"
move "%%F" "%%~dpF!newname!"
)
Se você realmente deseja renomear os arquivos e pastas em um único passo, então obviamente você deve remover a opção /A-D
. Mas menos óbvio é que você deve classificar o resultado do comando DIR decrescente para garantir que os filhos sejam processados antes dos pais, caso contrário, uma renomeação filho falhará porque o caminho listado não será mais válido.
@echo off
setlocal enableDelayedExpansion
set "old=V1"
set "new=newdocV2"
for /f "delims=" %%F in ('dir /b /s *.ods ^| sort /r') do (
set "newname=%%~nxF"
set "newname=!newname:%old%=%new%!"
move "%%F" "%%~dpF!newname!"
)
Agora, para uma série de coisas que podem dar errado, e como corrigi-las, bem como outras melhorias.
1) Um nome de arquivo ou pasta pode incluir o caractere !
(raro, mas possível). A expansão de uma variável FOR enquanto a expansão atrasada está ativada corromperá o valor se contiver !
. A solução é ativar e desativar a expansão atrasada dentro do loop.
2) O novo nome para o arquivo A pode coincidir com um nome já existente para o arquivo B, e o comando MOVE sobrescreverá B com A. O resultado final é apenas um arquivo, quando antes você tinha dois. Isso é provavelmente uma coisa ruim. A solução é usar o comando REN em vez de MOVE. Nesse caso, a renomeação falhará e acho que isso é bom. O comando REN requer o novo nome sem o caminho de destino.
3) Você provavelmente deseja uma listagem de como os arquivos / pastas foram renomeados. Isso é especialmente verdadeiro se você receber um erro, para que possa ver exatamente qual renomeação falhou. A solução simples é ECO o comando antes de executá-lo.
4) Não há necessidade de passar pelas moções de renomeação se o novo nome corresponder ao nome antigo. Isso é feito adicionando uma condição IF.
@echo off
setlocal disableDelayedExpansion
set "old=V1"
set "new=newdocV2"
for /f "delims=" %%F in ('dir /b /s *.ods ^| sort /r') do (
set "source=%%F"
set "oldname=%%~nxF"
setlocal enableDelayedExpansion
set "newname=!oldname:%old%=%new%!"
if /i "!newname!" neq "!oldname!" (
echo ren "!source!" "!newname!"
ren "!source!" "!newname!"
)
endlocal
)
Ainda há problemas em potencial. Por exemplo, o lote não possui um mecanismo para substituir o caractere =
em um valor variável. Este problema é bastante difícil de resolver com um lote puro.
A vida é muito mais simples se você simplesmente usar meu utilitário JREN.BAT - um script JScript / batch híbrido que usa expressões regulares para renomear arquivos ou pastas. O JREN.BAT é um script puro que é executado nativamente em qualquer máquina Windows do XP em diante. A documentação completa está disponível via JREN /?
. Você pode querer usar o JREN /?|MORE
, mas minha janela do console está configurada com um buffer grande que me permite navegar para ver as linhas anteriores, então não preciso de mais.
Você precisa entender expressões regulares para usar a ferramenta. Não é um problema nesse caso, mas se o termo de pesquisa ou substituição contiver meta- caracteres de expressão regular, eles precisarão de escape para obter a interpretação literal correta. Mas o poder das expressões regulares é incrível - permite que você seja muito específico sobre exatamente quais mudanças são feitas.
Eu uso a opção /I
para tornar a pesquisa insensível a maiúsculas / minúsculas.
O JREN.BAT renomeia apenas arquivos ou , de modo que requer dois comandos para renomear ambos.
jren "V1" "newdocV2" /i /s /fm "*.ods"
jren "V1" "newdocV2" /i /s /fm "*.ods" /d
Como o JREN é um script em lote, você deve usar CALL JREN
se colocar os comandos acima em outro script em lote.