带有 goto 命令的 Windows 批处理文件不起作用
我对 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 语句的其余迭代将不会被执行(日志错误文件夹包含多个文件)
有人可以提供帮助吗?
I have a problem with GOTO command and affiliated labels.
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
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?!
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)
Can someone provide help?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你有两个问题。
一个问题是 goto 破坏了 for 循环。
另一方面,括号中的标签相当困难。
goto 会中断always 和所有嵌套循环,即使goto 的标签位于同一块中,并且for 变量在跳转后立即丢失。
括号中的标签是“两行”导向的!
我尝试了标签,下面是括号的一些结果。
当出现标签时,下一行必须采用正确的“辅助”行格式。
这就是失败的原因。
对于第二行,跳过批处理解析器的一些步骤。
@
不起作用,@echo Hello
尝试启动名为@echo.bat
的文件。括号拆分失败,如
echo( hello
.标签作为文件名处理,
:echo
仅检查:echo
是否是有效的文件名,然后跳过这部分。::hello
在驱动器::
上搜索。出于测试目的,可以使用
subst :: c:\temp
创建驱动器::
。由于第二行上的标签被忽略,& 符号和管道也可以工作,但
::
上的文件必须存在。You've got two problems.
One problem is that a goto breaks a for-loop.
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.
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.
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
.Splitting of parenthesis fails, like in
echo( hello
.Labels are handeled as a file name,
:echo
checks only if:echo
is a valid file name and then skip this part.::hello
searches on the drive::
.For test purposes the drive
::
can be created withsubst :: c:\temp
.As labels are simply ignored on the second line, ampersands and also pipes work, but the file on
::
have to exist.注释/备注
:: 这是一个 REMark
冒号 (:),实际上是 LABEL 标记,可以通过将其加倍来代替 REM 用于注释 (: :),除了在括号内(即除了在FOR循环内)。
在循环中使用双标签可能会导致批处理脚本失败,但仅当:
换句话说:如果在循环中使用,双标签后面必须跟有包含正常的行(即有效)语法。即使单个标签也是有效的语法。
如果将双标签替换为 REM,则不会出现此错误。
出现双标签错误是因为 CMD.EXE 将 :: 解释为驱动器号(如 C:)。
。
注意 -
这是对 Jeb 的回答中提到的一个问题的解释,他提出了这一点但没有处理。
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 (i.e. except within a FOR loop).
Using a double-label within a loop can cause the batch script to fail, but ONLY if:
In other words: if used within a loop, the double-label must be followed by a line which contains normal (i.e. valid) syntax. Even a single-label is valid syntax.
This error never occurs if the double-label is replaced with REM.
The error arising from a double-label occurs because CMD.EXE interprets :: as a drive letter (like 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.