9

在两次遇到这个问题之后,我想我会在这里发布它,看看是否有人知道如何解决它。

我似乎无法使用 跳出嵌套循环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's 和else's 的条件中断?

4

6 回答 6

13

通过在标签中放置内部循环来中断。

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
于 2013-01-28T13:53:25.993 回答
6

您也可以使用与 FOR 相关联的控制变量在 break 之后省略其余的迭代:

@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 内的多个点处轻松设置中断。

安东尼奥

于 2013-02-02T01:37:35.813 回答
0

安东尼奥的提议非常好。我在示例中使用它来解析文件列表中的一些 CSV 或 HTML 文件。(嵌套 for 循环)。第一次看解析文件列表,第二次解析每个文件的内容。分隔符是 ; 或者 /。

@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
  )
 )
)
于 2016-12-14T08:45:14.297 回答
0

DEFINED可以出于多种原因行恶。我不建议使用它,除非您确切知道它是如何工作的以及所有潜在的用例。

避免在变量名中使用任何分隔符(空格、逗号等)是一种很好的做法,例如,如果变量名包含分隔符,IF DEFINED _variable 通常会失败。

一个更安全的答案,也不使用EXITor 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
于 2017-02-16T05:10:48.553 回答
0

欢迎来到 DOS BAT 及其所有地方性故障。最初 DOS BAT 不支持嵌套循环 _at _all;他们仍然不能完全正确地工作。为避免所有故障、怪异和不一致,请改用 Microsoft PowerShell。

您可以通过重组脚本以使用由“调用”语句调用的内部子例程来避免嵌套循环。使每个“for”都执行一个调用子例程的语句,而不是将动作放在内联块中。

一个密切相关的问题是,即使是顶级循环也似乎无法正常工作。那是因为 '( ... )' 便利结构在最初几年后被固定在 BAT 语言中,并且不能很好地与该语言的其余部分配合使用。特别是,当第一次进入块时,'( ... )' 中的 _everything 会被一次性替换。像 'if %NOMORE%==yes ...' 这样的构造行为不正常,因为 %NOMORE% 的值仅在输入块时被替换一次,_不是您每次执行时所期望的那样。因此,如果该值稍后被循环内部或外部的任何内容更改,则“if”测试将_看不到新值。

解决此问题的一种方法是笨拙地重组您的 BAT 文件,或者使用一堆“goto”,因此它不使用“(...)”,或者使用一堆对其他不需要的子例程的调用,或者两者兼而有之——这是 BAT wallahs 在引入块的语法便利之前多年所做的(伴随着奇怪的行为)。解决此问题的更好方法是使用“延迟扩展”(即“如果!NOMORE!==yes ...”而不是“如果 %NOMORE%==yes ...”)。[您的 Windows 版本必须支持延迟扩展,并且必须在您的 setlocal 语句中启用。]


由于新信息和对评论的回应,进行了大量编辑。(有关更多信息,请参阅第一条评论。)

于 2021-08-04T06:23:39.863 回答
-1

你能提供更多关于你的要求的信息吗?同时,如果它符合您的要求,您可以尝试一下。如果您需要更多信息,请随时通知我。

@echo off
for %%a in (1,2,3) do ( 
for %%b in (4,5,6) do (
echo Breaking
goto Break 
)
)
:Break
于 2013-01-28T13:25:56.450 回答