为了在一个文本文件的变量中存储多行,我使用了这个问题的答案:https://stackoverflow.com/a/10624240/1513458
使用这个脚本内联和解析大文件给了我一个最大的setlocal错误。为了解决这个问题,我将脚本放在一个子例程中,并从需要的行调用它。
在子例程终止之前,它底部的回声将输出预期的结果…但回到最初调用它的顶部,变量是空的。为什么会这样?
以下是脚本的简短版本:
setlocal EnableDelayedExpansion
set sourcefile=cc1
call :readfile %sourcefile%
echo !insert!
goto :EOF
:readfile
SETLOCAL DisableDelayedExpansion
set "insert="
FOR /F "usebackq 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=#!"
)
rem A echo !insert! here would output the expected result
goto :EOF
非常感谢你的帮助。批量显然不是为我准备的,但我需要通过这一点。
最佳答案
readfile例程的顶部有setlocal,用于本地化环境更改。当一个例程结束时,会为该例程中实例化的每个活动setlocal执行一个隐式endlocal。所以环境恢复到调用之前的状态。
不需要调用子例程。以前的代码在for循环中必须有setlocal而没有endlocal。这将导致max setlocal错误。现在for循环已经配对了setlocal/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