我有一个批处理脚本,它用源输入字符串替换源文本文件中多次出现的源字符串。
为此,我在这里使用了这个答案的略微更正版本: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
可悲的是,这根本没有任何好处。这会产生与我为整个脚本启用延迟扩展时相同的输出文件 我是否以错误的方式应用了给定的提示? (如果我进一步限制启用的范围,我只会在输出中得到空行或其他垃圾。)
答案 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命令的一部分。