DayedExpansion e problemas de substituição variável

2

Eu tenho este script em lote que percorre 5 variáveis de conjunto estático contendo um caminho de arquivo para um arquivo INI que ele então 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, parece estar desinfetando todas as instâncias de ! dentro do arquivo INI que, por sua vez, interrompe meu programa.

Acredito que as marcas ! estão sendo substituídas devido a DelayedExpansion, mas preciso executá-las aqui. Eu estou incluindo uma cópia da função com o problema, eu 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
    )
)
    
por Pyr3x 16.09.2015 / 02:35

1 resposta

1

Você obviamente tem uma expansão atrasada 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á ativada.

Uma solução é colocar um SETLOCAL / ENDLOCAL extra no loop interno para desativar temporariamente a expansão atrasada enquanto %%i é expandido.

Além disso, não é necessário TYPE o arquivo e não é necessário que o BREAK ímpar redirecionado crie um arquivo de saída vazio ou o redirecionamento de acréscimo no loop. Você pode simplesmente deixar FOR / F ler o arquivo diretamente e redirecionar uma vez fora do loop interno. Concedido, você deve gravar em um novo arquivo temporário e, em seguida, mova 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 via lote. Em vez disso, eu usaria JREPL.BAT - um utilitário JScript / batch híbrido executado nativamente em qualquer Máquina Windows do XP em diante :

FOR %%A IN (1 2 3 4 5) DO CALL JREPL "%IP_V%" "%IP%" /L /I /F "!CFG_%%A!" /O -

Muito mais simples, mais rápido e mais confiável: -)

    
por 16.09.2015 / 06:47

Tags