Problemas de expansão atrasada e substituição de variáveis

Problemas de expansão atrasada e substituição de variáveis

Eu tenho esse script em lote que percorre 5 variáveis ​​​​de conjunto estático contendo um caminho de arquivo para um INIarquivo 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 %%iestá 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 :-)

informação relacionada