Проблемы с задержкой расширения и заменой переменных

Проблемы с задержкой расширения и заменой переменных

У меня есть пакетный скрипт, который просматривает 5 статических переменных набора, содержащих путь к файлу, INIкоторый затем считывает и ищет определенную строку для замены.

Моя проблема в том, что после того, как if выполняет указанные замены и записывает файл обратно на диск, он, похоже, очищает все экземпляры в !INI-файле, что в свою очередь нарушает работу моей программы.

Я предполагаю, что !метки заменяются из-за DelayedExpansion, но мне это нужно для выполнения моих задач здесь. Я включаю копию функции с проблемой, я был бы очень признателен, если бы кто-то мог помочь мне разобраться с этим.

Я уже несколько дней пытаюсь найти ответ на этот вопрос…

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
    )
)

решение1

У вас, очевидно, есть отложенное расширение во всем опубликованном коде, и отложенное расширение происходит после расширения переменной FOR. Так что да, значение %%iповреждено, потому что включено отложенное расширение.

Одним из решений является добавление дополнительных SETLOCAL / ENDLOCAL во внутренний цикл для временного отключения отложенного расширения во время %%iрасширения.

Также нет необходимости вводить файл TYPE, и нет необходимости в странном перенаправленном BREAK для создания пустого выходного файла или в добавлении перенаправления внутри цикла. Вы можете просто позволить FOR /F напрямую прочитать файл и перенаправить один раз за пределы внутреннего цикла. Конечно, вы должны записать во временный новый файл, а затем переместить результат в исходное имя. Но это гораздо эффективнее (быстрее).

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
)

Примечание - Мне очень не нравится редактирование текстовых файлов через пакет. Вместо этого я бы использовалJREPL.BAT — гибридная утилита JScript/пакетного кода, которая изначально работает на любой машине Windows, начиная с XP.:

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

Гораздо проще, быстрее и надежнее :-)

Связанный контент