延迟扩展和变量替换问题

延迟扩展和变量替换问题

我有这个批处理脚本,它翻阅 5 个静态设置变量,INI这些变量包含一个文件的文件路径,然后读取并搜索要替换的特定字符串。

我的问题是,如果执行上述替换并将文件写回磁盘后,它似乎正在清理!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扩展时暂时禁用延迟扩展。

此外,无需键入文件,也无需奇怪的重定向 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/批处理实用程序,可在 XP 及以上版本的任何 Windows 计算机上本地运行

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

更简单,更快捷,更可靠:-)

相关内容