简体   繁体   English

带有 goto 命令的 Windows 批处理文件不起作用

[英]windows batch file with goto command not working

I have a problem with GOTO command and affiliated labels.我的 GOTO 命令和附属标签有问题。

Facts: Given a bunch of files from a folder (they are log errors) I need to open them and check if they contain a specific string.事实:给定文件夹中的一堆文件(它们是日志错误),我需要打开它们并检查它们是否包含特定字符串。 If yes then eliminate some characters (all the chars after the last appearance of "_", including itself) from the file names and do other operations.如果是,则从文件名中删除一些字符(最后一次出现“_”之后的所有字符,包括它自己)并执行其他操作。

For cutting off the chars I'm using GOTO command in a loop manner as I found it described here: http://www.robvanderwoude.com/battech_while_loops.php为了切断字符,我以循环方式使用 GOTO 命令,因为我发现它在这里描述: http : //www.robvanderwoude.com/battech_while_loops.php

The script is:脚本是:

@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

The script is not running because there is an empty line after the label loopEnd?!脚本没有运行,因为标签 loopEnd 后面有一个空行?! If I'm writing any instructions right after that label they will be executed but the rest of iterations from the first for statement won't be executed (the log errors folder contains more one file)如果我在该标签之后立即编写任何指令,它们将被执行,但不会执行第一个 for 语句的其余迭代(日志错误文件夹包含更多一个文件)

Can someone provide help?有人可以提供帮助吗?

You've got two problems.你有两个问题。

One problem is that a goto breaks a for-loop.一个问题是 goto 会破坏 for 循环。 The other, labels are quite difficult in parenthesis.另一方面,括号中的标签非常困难。

The goto breaks always and all nested loops, even if the label of the goto is in the same block, and the for-variables are lost immediately after the jump. goto 总是和所有嵌套循环中断,即使 goto 的标签在同一个块中,并且在跳转后立即丢失 for 变量。

In parenthesis lables are "two line" oriented!括号中的标签是“两行”导向的! I experimented with labels and here are some results for parenthesis.我尝试了标签,这里有一些括号的结果。

When a label occurs, the next line has to be in the correct format for a "secondary" line.出现标签时,下一行必须采用“辅助”行的正确格式。

That's why this fails.这就是失败的原因。

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

For the second line some steps of the batch parser are skipped.对于第二行,跳过了批处理解析器的一些步骤。

@ doesn't work, @echo Hello tries to start a file named @echo.bat . @不起作用, @echo.bat @echo Hello尝试启动一个名为@echo.bat的文件。

Splitting of parenthesis fails, like in echo( hello .括号的拆分失败,就像在echo( hello .
Labels are handeled as a file name, :echo checks only if :echo is a valid file name and then skip this part.标签作为文件名处理, :echo仅检查:echo是否为有效文件名,然后跳过这部分。

::hello searches on the drive :: . ::hello在驱动器上搜索::
For test purposes the drive :: can be created with subst :: c:\\temp .出于测试目的,驱动器::可以使用subst :: c:\\temp
As labels are simply ignored on the second line, ampersands and also pipes work, but the file on :: have to exist.由于标签在第二行被简单地忽略,与号和管道也可以工作,但::上的文件必须存在。

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

Comments / Remarks评论/备注

:: This is a REMark ::这是一个重新标记

A colon (:), which is actually the LABEL tag, can be used for comments instead of REM, by doubling it (::), except within parentheses (ie except within a FOR loop).冒号(:),这实际上是LABEL标签,可用于注释代替REM,通过加倍它(::),除了括号内(即除在for循环内)。

Using a double-label within a loop can cause the batch script to fail, but ONLY if:在循环中使用双标签会导致批处理脚本失败,但仅限于:

  • The double-label is followed by a second double-label on the next line双标后跟下一行的第二个双标
  • The double-label is followed by an empty line on the next line双标后跟在下一行的
  • The double-label is the last line in the loop双标是循环中的最后一行

In other words: if used within a loop, the double-label must be followed by a line which contains normal (ie valid) syntax.换句话说:如果在循环中使用,双标签后面必须跟一行包含正常(即有效)语法的行。 Even a single-label is valid syntax.即使是单标签也是有效的语法。

This error never occurs if the double-label is replaced with REM.如果用 REM 替换双标签,则不会发生此错误。

The error arising from a double-label occurs because CMD.EXE interprets :: as a drive letter (like C:).由于 CMD.EXE 将 :: 解释为驱动器号(如 C:),因此出现双标签错误。

. .

Note - This is an explanation for one of the problems mentioned in Jeb's answer, a point which he raises but doesn't deal with.注意- 这是对 Jeb 的回答中提到的一个问题的解释,这是他提出但没有处理的一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM