Windows批处理文件 - 在变量值中使用感叹号而不禁用延迟扩展

时间:2015-10-22 14:34:34

标签: windows batch-file

我有一个批处理脚本,它用源输入字符串替换源文本文件中多次出现的源字符串。
为此,我在这里使用了这个答案的略微更正版本:How to replace substrings in windows batch file
(这不是公认的答案,被接受的答案确实会更改源文件!)但我只能解决一点问题,并且每个行都添加一个空格" -bug,而不是主要问题无法使用带有感叹号的源文件!

对于这个剩下的问题,我研究了一些问题,例如找到(并尝试了以下建议)这些主题:
- exclamation point being removed constantly in batch file
- Windows batch - Delayed expansion removes exclamation mark
可悲的是这些问题'解决方案(暂时禁用"延迟扩展")不适用于我,因为我的脚本中有一行需要"延迟扩展" AND必须处理带有潜在惊叹号的变量值!

这是行
SET modified=!string:%SEARCHTEXT%=%REPLACETEXT%!
在我的第一个链接后可以看到它的背景 作为简短说明:该行需要延迟扩展才能起作用,因为它位于for-block中的if-else块内。另一方面,变量' string'的值。可以包含感叹号,因为它会逐行扫描源文件。

有人知道如何解决这个问题吗?

修改
根据第一条评论,我试图仅对主循环的必要部分启用延迟扩展(仅在需要访问修改后的变量内容时,使用"!" -operator)。整个主循环现在看起来像这样:


    setlocal disabledelayedexpansion
    for /f "tokens=1,* delims=¶" %%A in ('"findstr /n ^^ %INTEXTFILE%"') do (
      SET string=%%A
      setlocal enabledelayedexpansion
      for /f "delims=: tokens=1,*" %%A in ("!string!") do set "string=%%B"
      if  "!string!" == "" (
        echo.>>%OUTTEXTFILE%
      ) else (
        SET modified=!string:%SEARCHTEXT%=%REPLACETEXT%!
        echo !modified!>> %OUTTEXTFILE%
      )
      endlocal
    )
    endlocal

可悲的是,这根本没有任何好处。这会产生与我为整个脚本启用延迟扩展时相同的输出文件 我是否以错误的方式应用了给定的提示? (如果我进一步限制启用的范围,我只会在输出中得到空行或其他垃圾。)

1 个答案:

答案 0 :(得分:1)

您编辑的代码中存在多个错误。

您正在使用findstr/n,这会在每行前面加上行号和冒号 但是你应该避免将delim设置为,因为即使它是一个不常见的角色,它仍然是一个可能的角色。

稍后您尝试使用

删除行号和冒号
for /f "delims=: tokens=1,*" %%A in ("!string!") do set "string=%%B"

但是这也将删除输入文件的所有前导冒号并销毁所有惊叹号,有时也会影响插入符号。

更好地使用

set "string=!string:*:=!" Remove all up to the first colon

然后你的两条回音线都不好 echo.很慢,可能会失败 当echo !variable!

中的内容错误时,variable会失败

所以我们最终得到了

setlocal disabledelayedexpansion
for /f "tokens=* delims=" %%A in ('"findstr /n ^^ %INTEXTFILE%"') do (
  SET "string=%%A"
  setlocal EnableDelayedExpansion
  set "string=!string:*:=!"
  if defined string (
    SET modified=!string:%SEARCHTEXT%=%REPLACETEXT%!
  )
    (echo(!modified!) >> %OUTTEXTFILE%
  endlocal
)
endlocal

回声线看起来有点奇怪,但它或多或少都很简单 首先,我将一个普通的回显包含在括号内,以确保我不会在文件中添加不需要的空格,因此我可以根据需要在结束括号后添加任意数量的空格。

(echo Sample)    >> myOutputFile.txt

但是由于我们需要扩展具有未知内容的变量,因此这里不能使用普通的ECHO,请参阅此示例。

set "var1=/?"
set "var2=    "
set "var3=ON"
echo %var1%
echo %var2%
echo %var3%

echo(可以安全地处理任何内容。它看起来很奇怪,但目前还没有人知道。

所以我只需将echo(!variable!括在括号(echo(!variable!)中,其中只有外括号构建块,第二个左括号是echo命令的一部分。