Eu tenho esse script em lote que percorre 5 variáveis de conjunto estático contendo um caminho de arquivo para um INI
arquivo que ele lê e procura por uma string específica para substituir.
Meu problema é que, depois de fazer as substituições e gravar o arquivo de volta no disco, ele parece estar limpando todas as instâncias do !
arquivo INI, o que, por sua vez, interrompe meu programa.
Suponho que as !
marcas estejam sendo substituídas devido ao DelayedExpansion, mas preciso delas para executar minhas tarefas aqui. Estou incluindo uma cópia da função com o problema. Ficaria muito grato se alguém pudesse me ajudar a descobrir isso.
Estou preso tentando encontrar uma resposta para isso há dias ...
FOR %%A IN (1 2 3 4 5) DO (
SET CFG_A=!CFG_%%A!
IF "%DEBUG%"=="1" ECHO !CFG_A!
FOR /f "delims=" %%i IN ('type "!CFG_A!" ^& break ^> "!CFG_A!" ') DO (
SET "line=%%i"
SETLOCAL enabledelayedexpansion
SET "line=!line:%IP_V%=%IP%!"
>>"!CFG_A!" echo(!line!
ENDLOCAL
)
)
Responder1
Obviamente, você atrasou a expansão em todo o código postado, e a expansão atrasada ocorre após a expansão da variável FOR. Então, sim, o valor de %%i
está corrompido porque a expansão atrasada está habilitada.
Uma solução é colocar um SETLOCAL / ENDLOCAL extra em seu loop interno para desativar temporariamente a expansão atrasada enquanto %%i
é expandida.
Além disso, não há necessidade de TYPE o arquivo e não há necessidade do estranho BREAK redirecionado para criar um arquivo de saída vazio ou do redirecionamento anexado dentro do loop. Você pode simplesmente deixar FOR /F ler o arquivo diretamente e redirecionar uma vez fora do loop interno. É verdade que você deve gravar em um novo arquivo temporário e depois mover o resultado para o nome original. Mas isso é muito mais eficiente (mais rápido).
FOR %%A IN (1 2 3 4 5) DO (
IF "%DEBUG%"=="1" >&2 ECHO(!CFG_%%A!
(FOR /f "usebackq delims=" %%i IN ("!CFG_%%A!") DO (
SETLOCAL disableDelayedExpansion
SET "line=%%i"
SETLOCAL enableDelayedExpansion
SET "line=!line:%IP_V%=%IP%!"
echo(!line!
ENDLOCAL
ENDLOCAL
))>"!CFG_%%A!.new"
MOVE /Y "!CFG_%%A!.new" "!CFG_%%A!" >nul
)
Nota - eu realmente não gosto de editar arquivos de texto em lote. Em vez disso, eu usariaJREPL.BAT - um utilitário híbrido JScript/lote que roda nativamente em qualquer máquina Windows a partir do XP:
FOR %%A IN (1 2 3 4 5) DO CALL JREPL "%IP_V%" "%IP%" /L /I /F "!CFG_%%A!" /O -
Muito mais simples, rápido e confiável :-)