Windows批处理文件与goto命令无法正常工作

时间:2010-10-20 14:00:01

标签: windows file batch-file command goto

我的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语句的其余迭代将不会被执行(日志错误文件夹包含更多的一个文件)

有人可以提供帮助吗?

2 个答案:

答案 0 :(得分:12)

你有两个问题。

一个问题是goto打破了for循环。 另外,标签在括号中很难。

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

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

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

这就是失败的原因。

(
: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 ::

答案 1 :(得分:1)

评论/备注

:: 这是一个REMark

冒号(:),实际上是LABEL标记,可通过将括号(<:>除外)加倍(即:FOR循环中的除外),将其用作注释而不是REM。 )。

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

  • 双标签后接下一行 second 双标签
  • 双标签后的下一行是 empty
  • 双标签是循环的最后一行

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

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

由于CMD.EXE将::解释为驱动器号(如C :),因此出现了由双标签引起的错误。