У меня есть пакетный скрипт, который просматривает 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 -
Гораздо проще, быстрее и надежнее :-)