4

我对 GOTO 命令和附属标签有疑问。

事实:给定文件夹中的一堆文件(它们是日志错误),我需要打开它们并检查它们是否包含特定的字符串。如果是,则从文件名中删除一些字符(“_”最后一次出现之后的所有字符,包括它自己)并执行其他操作。

为了切断字符,我以循环方式使用 GOTO 命令,因为我发现它在这里描述:http ://www.robvanderwoude.com/battech_while_loops.php

脚本是:

@echo off
setlocal EnableDelayedExpansion

cls

for %%X in (D:\e-pub\outbox\logs\*.*) do (

    for /F "tokens=7" %%S in (%%X) do (

        if /i "%%S"=="<ml>" (
            SET fisier=%%~nX
            SET cond=!fisier:~-1!
            SET fisier=!fisier:~0,-1!

            :loopStart
            rem condition to break the loop
            if !cond!==_ goto loopEnd
            SET cond=!fisier:~-1!
            SET fisier=!fisier:~0,-1!
            goto loopStart

            :loopEnd

            rem here it should be out of a loop
            rem other stuff to do with var !fisier!
            rem the following line is not executed because of the label loopEnd
            echo !fisier!
        )
    )
) 

pause

脚本没有运行,因为标签 loopEnd 后面有一个空行?!如果我在该标签之后编写任何指令,它们将被执行,但不会执行第一个 for 语句的其余迭代(日志错误文件夹包含多个文件)

有人可以提供帮助吗?

4

2 回答 2

12

你有两个问题。

一个问题是 goto 会破坏 for 循环。另一方面,括号中的标签非常困难。

goto 总是中断所有嵌套循环,即使 goto 的标签在同一个块中,并且 for 变量在跳转后立即丢失。

括号中的标签是“两行”导向的!我尝试了标签,这里有一些括号的结果。

出现标签时,下一行必须采用“辅助”行的正确格式。

这就是失败的原因。

(
:this label fails with a syntax error
)

(
:this works
:because this line is a "legal" secondary line
)

(
:: The remark style
:: fails, because it's not "legal" to use a double colon, because it's not a legal path (in the most cases)
)

(
:and now I got courious & echo This will not echo'd
:but & echo You can see this !
)

对于第二行,跳过了批处理解析器的一些步骤。

@不起作用,@echo Hello尝试启动一个名为@echo.bat.

括号拆分失败,如echo( hello.
标签作为文件名处理,:echo仅检查是否:echo是有效文件名,然后跳过这部分。

::hello在驱动器上搜索::
出于测试目的,::可以使用subst :: c:\temp.
由于标签在第二行被简单地忽略,&符号和管道也可以工作,但文件::必须存在。

(
echo @echo This is %~f0
) > %TEMP%\testLabel.bat

REM create Drive ::
subst :: %temp% 
(
:Label 
::\testLabel.bat The bat will not be executed | echo But this
)
subst /D ::
于 2010-10-23T20:51:56.803 回答
3

评论/备注

:: 这是一个备注

冒号 (:),实际上是 LABEL 标记,可用于注释而不是 REM,方法是将它加倍 (::),括号内除外(即 FOR 循环内除外)。

在循环中使用双标签可能会导致批处理脚本失败,但仅在以下情况下:

  • 双标签之后是下一行的第二个双标签
  • 双标签后跟下一行的
  • 双标签是循环中的最后一行

换句话说:如果在循环中使用,双标签后面必须跟一个包含正常(即有效)语法的行。即使是单标签也是有效的语法。

如果将双标签替换为 REM,则不会发生此错误。

出现双标签错误是因为 CMD.EXE 将 :: 解释为驱动器号(如 C:)。

.

注意- 这是对 Jeb 回答中提到的问题之一的解释,他提出但没有处理这一点。

于 2020-05-24T04:17:31.693 回答