您的 :readfile 例程在顶部有 SETLOCAL,用于本地化环境更改。当例程结束时,对于在例程中实例化的每个活动 SETLOCAL 都会执行一个隐式 ENDLOCAL。因此环境恢复到调用之前存在的状态。
不需要调用的子程序。您之前的代码在 FOR 循环中必须有没有 ENDLOCAL 的 SETLOCAL。这将导致最大 SETLOCAL 错误。现在你的 FOR 循环已经配对了 SETLOCAL/ENDLOCAL,所以没有更多问题了。
可以跨 ENDLOCAL 屏障传输任何值,但它使用了一种先进的技术。
一些简单的重组避免了这样做的需要。但要小心 - 批处理变量不能包含超过 8192 个字符。
setlocal disableDelayedExpansion
set sourcefile=cc1
set "insert="
for /f "delims=" %%a in ('findstr /n "^" "%SOURCELOC%\%~1.txt"') do (
set "line=%%a"
setlocal EnableDelayedExpansion
set "line=!line:#=#S!"
set "line=!line:*:=!"
for /f "delims=" %%p in ("!insert!#L!line!") do (
endlocal
set "insert=%%p"
)
)
setlocal EnableDelayedExpansion
if defined insert (
set "insert=!insert:~2!"
set ^"insert=!insert:#L=^
!"
set "insert=!insert:#S=#!"
)
echo !insert!
编辑
这是一个演示跨 ENDLOCAL 边界返回任何值的解决方案(除了它不支持回车。有一个简单的扩展支持回车)。该例程将给出正确的结果,无论它是在启用还是禁用延迟扩展的情况下调用的。该技术是由 DosTips 用户 jeb 开发的: http://www.dostips.com/forum/viewtopic.php?f=3&t=1839和此处:http : //www.dostips.com/forum/viewtopic.php ?p=6930#p6930。在那里你会找到一些关于它是如何工作的解释,但它不适合胆小的人。
@echo off
setlocal enableDelayedExpansion
set sourceloc=.
set sourcefile=test
set ^"LF=^
^"
call :readFile "%sourcefile%"
echo(!insert!
exit /b
:readFile
setlocal
set "notDelayed=!"
setlocal disableDelayedExpansion
set "insert="
for /f "delims=" %%a in ('findstr /n "^" "%SOURCELOC%\%~1.txt"') do (
set "line=%%a"
setlocal EnableDelayedExpansion
set "line=!line:%%=%%J!"
set "line=!line:*:=!"
for /f "delims=" %%p in ("!insert!%%~L!line!") do (
endlocal
set "insert=%%p"
)
)
setlocal enableDelayedExpansion
if defined insert (
set "insert=!insert:"=%%~K!"
if not defined notDelayed set "insert=!insert:^=^^^^!"
)
if defined insert if not defined notDelayed set "insert=%insert:!=^^^!%" Do not remove!
set "replace=%% """"
for %%L in ("!LF!") do for /f "tokens=1,2" %%J in ("!replace!") do (
endlocal
endlocal
endlocal
set "insert=%insert%" Do not remove!
)
exit /b