为了在文本文件的变量中存储多行,我使用的是这个问题的答案: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
非常感谢你的帮助。批量显然不适合我,但我需要坚持这一点。
答案 0 :(得分:3)
您的: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
答案 1 :(得分:0)
试试这个:
setlocal EnableDelayedExpansion
set sourcefile=cc1
call :readfile insert
echo %insert%
goto :EOF
:readfile
SETLOCAL DisableDelayedExpansion
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=#!"
)
rem A echo !insert! here would output the expected result
SET "%1=!insert!"
ENDLOCAL
goto :EOF