gpt4 book ai didi

windows - 从子程序返回变量,不工作...为什么?

转载 作者:可可西里 更新时间:2023-11-01 11:32:24 25 4
gpt4 key购买 nike

为了在文本文件的变量中存储多行,我使用了这个问题的答案: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。这将导致最大 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

关于windows - 从子程序返回变量,不工作...为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18052965/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com