带有goto命令的Windows批处理文件不起作用
Posted
技术标签:
【中文标题】带有goto命令的Windows批处理文件不起作用【英文标题】:windows batch file with goto command not working 【发布时间】:2011-04-28 01:52:28 【问题描述】:我对 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 语句的其余迭代(日志错误文件夹包含多个文件)
有人可以提供帮助吗?
【问题讨论】:
显示您的日志文件样本,其中包含要查找的字符串,以及您需要删除的内容。显示你想要的最终输出。 从我的角度来看,这与内容无关,而与做事的方式有关 【参考方案1】:你有两个问题。
一个问题是 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 ::
【讨论】:
一件事。在第二个示例中,您引入了第二个标签。就 cmd.exe 而言,第二个标签是否不需要另一条“法律线”? Tnx 的解释。 不,如果标签在“辅助行”中,则不需要另一个“辅助行”。 sec-line 的解析方式与其他的不同,正如您在上一个示例中看到的那样 感谢您的回答和您的时间 我只想修改一下: 1. 缩进根本不影响行为; 2.在最后一个例子中,当你用&
替换管道|
时结果是一样的(所以结果肯定不是由管道初始化的新cmd
实例引起的)......【参考方案2】:
评论/备注
:: 这是一个备注
冒号 (:),实际上是 LABEL 标记,可用于 cmets 而不是 REM,方法是将它加倍 (::), except 在括号内(即除了在 FOR 循环中)。
在循环中使用双标签会导致批处理脚本失败,但仅在以下情况下:
双标签后跟 second 双标签在下一行 双标签后跟下一行的空行 双标签是循环中的最后一行换句话说:如果在循环中使用,双标签后面必须跟一个包含正常(即有效)语法的行。即使是单标签也是有效的语法。
如果将双标签替换为 REM,则不会出现此错误。
出现双标错误是因为 CMD.EXE 将 :: 解释为驱动器号(如 C:)。
.
注意 - 这是对 Jeb 回答中提到的问题之一的解释,他提出了这一点但没有处理。
【讨论】:
以上是关于带有goto命令的Windows批处理文件不起作用的主要内容,如果未能解决你的问题,请参考以下文章
IF EXIST C:\directory\ goto a else goto b 问题 windows XP 批处理文件