在遇到这个问题两次后,我想我会在这里发布,看看是否有人知道如何绕过它。
我似乎无法使用goto
打破嵌套循环,因为它看起来就像它突破内循环时,括号因此从未到达内部结束循环。
我已将其缩小为一个非常简单的例子
for %%a in (1,2,3) do (
for %%b in (4,5,6) do (
echo Breaking
goto :BREAK
)
:BREAK
)
这会导致错误
) was unexpected at this time.
我认为可能添加额外的括号可能会解决问题,但除非我知道我要打破,否则它将无法解决,如果这是一个有条件的突破,那就是同样的问题。
是否有任何简单的替代方法可以将内循环分解回外部,即使是使用if
和else
的条件中断?
答案 0 :(得分:10)
通过在标签中放置内循环来中断。
for %%a in (1, 2, 3) DO (
call :innerloop
)
:innerloop
for %%b in (4, 5, 6) DO (
if %%b==<something> (
echo break
goto :break
)
)
:break
答案 1 :(得分:5)
在中断后,您还可以省略与FOR:
相关联的控制变量的剩余迭代次数@echo off
for %%a in (1,2,3) do (
echo Top-level loop: %%a
set break=
for %%b in (4,5,6) do if not defined break (
echo Nested loop: %%a-%%b
if %%b == 4 (
echo Breaking
set break=yes
)
)
)
此方法将嵌套for-body的代码保留在其原始位置,并允许在for-body内的多个点处轻松设置中断。
安东尼奥
答案 2 :(得分:0)
@dir /O /B j:\temp\*.txt > j:\temp\filelist.doc
@for /F "tokens=1" %%a in (j:\temp\filelist.doc) DO (
@echo j:\temp\%%a
@set ef=
@for /F "delims=;/ tokens=1,2,3,4,5,6,7*" %%b in (j:\temp\%%a) DO @if not defined ef (
@if %%e == CNAME (
@echo Do something here
@set ef=yes
)
)
)
答案 3 :(得分:0)
DEFINED
可以为多个reasons做恶。除非您确切知道它是如何工作的以及所有潜在的用例,否则我不建议使用它。
最好避免使用任何分隔符(空格, 变量名中的逗号等),例如IF DEFINED _variable 如果变量名称包含分隔符,则通常会失败。
更安全的答案,也不使用EXIT
或GOTO
:
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
Set time_to_exit=false
FOR /L %%O IN (1,1,3) DO (
echo [ Outer ] loop iteration %%O
FOR /L %%I IN (1,1,3) DO (
IF NOT "!time_to_exit!"=="true" (
echo ]Inner[ loop iteration %%I
IF "%%O"=="2" Set time_to_exit=true
)
)
)
输出:
[ Outer ] loop iteration 1
]Inner[ loop iteration 1
]Inner[ loop iteration 2
]Inner[ loop iteration 3
[ Outer ] loop iteration 2
]Inner[ loop iteration 1
[ Outer ] loop iteration 3
答案 4 :(得分:0)
欢迎使用 DOS BAT 及其所有常见故障。原来DOS BAT不支持嵌套循环_at _all;他们仍然不能完全正确地工作。为避免所有故障、怪异和不一致,请改用 Microsoft PowerShell。
您可以通过重构脚本以使用由“call”语句调用的内部子例程来避免嵌套循环。使每个“for”执行一个调用子例程的语句,而不是将操作放在内联块中。
一个密切相关的问题是,即使跳出顶级循环似乎也不太常见。那是因为 '( ... )' 便利结构是在原始语言出现几年后用螺栓固定在 BAT 语言上的,并且与该语言的其余部分不能很好地配合使用。特别是,当第一次进入块时,'( ... )' 中的 _everything 被一劳永逸地替换。像 'if %NOMORE%==yes ...' 这样的构造行为不正常,因为 %NOMORE% 的值在块被输入时只被替换一次, _not 每次执行时都像你期望的那样。因此,如果该值稍后被循环内部或外部的任何内容更改,则“if”测试将_看不到新值。
解决这个问题的一种方法是笨拙地重组你的 BAT 文件,要么使用一堆“goto”,以便它不使用“( ... )”,要么调用一堆其他不需要的子程序,或者两者兼而有之——这就是 BAT wallahs 在引入块的语法便利性之前多年所做的事情(伴随着它的奇怪行为)。解决此问题的更好方法是使用“延迟扩展”(即“if !NOMORE!==yes ...”而不是“if %NOMORE%==yes ...”)。 [您的 Windows 版本必须支持延迟扩展,并且必须在您的 setlocal 语句中启用。]
由于新信息和对评论的回应,进行了大量编辑。 (有关更多信息,请参阅第一条评论。)
答案 5 :(得分:-1)
您能否提供有关您的要求的更多信息? 在此期间,如果符合您的要求,您可以试试这个。 如果您需要更多,请随时发布。
@echo off
for %%a in (1,2,3) do (
for %%b in (4,5,6) do (
echo Breaking
goto Break
)
)
:Break