批处理文件如何循环遍历类似于开关的参数?

10

我正在尝试循环遍历传递给批处理文件的参数。根据参数,我想设置一个变量标志为true或false,以便在脚本后面使用。

因此,我的命令是"myscript.bat /u /p /s"

我的代码如下:

FOR /f %%a IN ("%*") DO (
  IF /I "%%a"=="/u" SET UPDATE=Y
  IF /I "%%a"=="/p" SET PRIMARY=Y
  IF /I "%%a"=="/s" SET SECONDARY=Y
)

只有当我只传递一个参数时它才能正常工作,这告诉我它将整个参数列表作为单个参数获取。我尝试过使用 "delims=" 但没有成功。您有什么关于获取每个以空格分隔的参数的想法吗?


如果给其中一个参数添加值怎么办?

myscript.bat /u /p /d TEST /s

:loop
IF "%~1"=="" GOTO cont
IF /I "%~1"=="/u" SET UPDATE=Y
IF /I "%~1"=="/p" SET PRIMARY=Y
IF /I "%~1"=="/s" SET SECONDARY=Y
IF /I "%~1"=="/d" SHIFT & SET DISTRO="%~1"
SHIFT & GOTO loop

:cont

但是与最后一个IF语句一起出现的SHIFT实际上没有移动任何内容。 DISTRO最终变成了"/d"而不是"TEST"。

2个回答

24

你的原始代码不算太错,但由于我不喜欢GOTO循环,所以我想贴出这个:

FOR %%a IN (%*) DO (
  IF /I "%%a"=="/u" SET UPDATE=Y
  IF /I "%%a"=="/p" SET PRIMARY=Y
  IF /I "%%a"=="/s" SET SECONDARY=Y
)

只有一个参数时能够正常工作的原因是过度使用了引号。通过将%*放在引号中,您使整个命令行成为一个单一的标记。另外,“FOR”的/F变体也不是你要找的东西。从FOR /?中获得的文档应该有助于澄清事情。


6
你可以使用SHIFT、GOTO和额外的IF循环遍历参数,并检查是否没有更多的参数需要解析:
:loop
IF "%~1"=="" GOTO cont
IF /I "%~1"=="/u" SET UPDATE=Y
IF /I "%~1"=="/p" SET PRIMARY=Y
IF /I "%~1"=="/s" SET SECONDARY=Y
SHIFT & GOTO loop

:cont
...

更新(解决参数本身带有参数的情况)

在检查/d的IF语句中,SHIFT确实起作用。问题在于整行代码一次性被评估,两个%~1实例都被替换为同一个值,即此时为/d

因此,在这种情况下的解决方案是让解释器分别评估SET DISTRO="%~1"部分和IF /I "%~1"=="/d"部分。有多种方法可以实现这一点。例如,您可以将SHIFT & SET DISTRO="%~1"移到下一行,并在%~1不是/d时跳过它:

...
IF /I NOT "%~1"=="/d" GOTO skip_d
SHIFT & SET "DISTRO=%~1"
:skip_d
...

另一种方法是将特殊值(例如?)分配给DISTRO,并在遇到/d时进行移位。然后,在下一行中,检查DISTRO是否具有该特殊值,并将其设置为%~1
...
IF /I "%~1"=="/d" SHIFT & SET DISTRO=?
IF "%DISTRO%"=="?" SET "DISTRO=%~1"
...

谢谢!我想我想太多了。 - DssTrainer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接