Erro de lote clássico: -)
O comando SET está funcionando bem. É a sua expansão que está falhando.
A expansão %VAR%
ocorre quando a instrução é analisada e todos os comandos dentro do loop FOR são analisados de uma só vez. O mesmo é verdadeiro para qualquer bloco de código entre parênteses. Portanto, os valores de %fullpath%
e %basename%
são constantes durante a execução do loop FOR - os valores que existiam antes da inserção do loop (indefinido nesse caso).
A correção é usar a expansão atrasada, que ocorre imediatamente antes do comando ser executado. A expansão atrasada deve ser ativada com setlocal enableDelayedExpansion
antes de poder ser usada. E a sintaxe da expansão muda para !VAR!
.
@echo off
setlocal enableDelayedExpansion
for /f "tokens=*" %%G in ('dir /s /b /a:d "e:\tmp\*"') do (
echo %%G
set fullpath=%%G
set basename=!fullpath:~7!
echo !fullpath!
echo !basename!
)
Mas ainda há um problema em potencial. Os nomes dos arquivos podem conter o caractere !
e qualquer variável FOR contendo !
será corrompida na expansão quando a expansão atrasada estiver ativada. A solução é ativar e desativar a expansão atrasada dentro do loop.
@echo off
for /f "tokens=*" %%G in ('dir /s /b /a:d "e:\tmp\*"') do (
echo %%G
set fullpath=%%G
setlocal enableDelayedExpansion
set basename=!fullpath:~7!
echo !fullpath!
echo !basename!
endlocal
)
Se você precisar proteger !
literais e precisar das atribuições de variáveis para persistir entre as iterações, a melhor coisa a fazer é usar um procedimento CALLed para que você possa usar a expansão normal. Simplesmente transfira o valor da variável FOR para um parâmetro CALL. Mas usar CALL é significativamente mais lento do que colocar tudo diretamente no loop.
@echo off
for /f "tokens=*" %%G in ('dir /s /b /a:d "e:\tmp\*"') do call :proc "%%G"
exit /b
:proc
echo %~1
set "fullpath=%~1"
set "basename=%fullpath:~7%"
echo %fullpath%
echo %basename%
exit /b