最不复杂的解决方案(以我的拙见)是使用子程序来set str
. 超过一级的延迟扩张往往会导致严重的脑损伤。哦,您可能可以set str
通过执行以下操作来修复您的线路
call call call set str=%%%%str:%%tobereplaced%%=%replacewith%%%%%
...或类似的。明白我说的脑损伤是什么意思吗?很难遵循递归。
所以这是我对解决方案的建议。我还解决了另一个或两个潜在问题。由于您正在对 *.txt 进行递归搜索,因此我使for
循环能够处理它们在子目录中找到的任何文本文件。我还没有对此进行测试,所以如果您遇到任何奇怪的错误,请告诉我。
@echo off
setlocal enabledelayedexpansion
set replacewith=whatever
for /r %%g in (*.txt) do (
set newfile=%%~dpng.new%%~xg
for /F "tokens=3 delims=<>" %%i in ('findstr "volumelabel" "%%g"') do (
set "tobereplaced=%%i"
echo %%~nxg has !tobereplaced! to be replaced by %replacewith%
rem combining your for loops this way makes the second only fire if the first is true
rem using "findstr /n" in your for loop preserves blank lines
for /F "delims=" %%a in ('findstr /n "^" "%%g"') do (
rem ...but you have to strip off the line numbers
set "str=%%a" && set "str=!str:*:=!"
rem "call :repl" to work around the delayed expansion conundrum
call :repl "!str!" "!tobereplaced!" "%replacewith%" str
echo !str!>>!newfile!
)
)
)
goto :EOF
:repl <line> <find> <replace> <var>
setlocal enabledelayedexpansion
set "line=%~1"
set "line=!line:%~2=%~3!"
set "%4=%line%"
goto :EOF
警告:如果您的文本文件包含感叹号、等号或克拉,它们可能不会进入 textfile.new.txt。
对于它的价值,如果我在你的位置,而不是使用批处理文件,我可能会使用sed(二进制文件应该是你所需要的)。你甚至不需要脚本。你可以像这样作为一个班轮来做:
for /r %I in (*.txt) do sed -r "s/volumelabel/replacement/ig" "%I" > "%~dpnI.new%~xI"
顺便说一句,有关这种符号help for
的解释,请参阅最后几页。%~dpnI