【问题标题】:Batch file for loop through switch-like arguments?通过类似开关的参数循环的批处理文件?
【发布时间】:2026-01-23 07:20:03
【问题描述】:

我正在尝试遍历传递给批处理文件的参数。根据参数,我想设置一个变量标志 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”

【问题讨论】:

    标签: batch-file for-loop dos


    【解决方案1】:

    你的原创作品离你不远了,因为我不喜欢 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 /? 提供的文档应该能帮我们解决问题。

    【讨论】:

      【解决方案2】:

      您可以使用 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
      ...
      

      UPDATE(解决参数有自己的参数的情况)

      在 IF 语句中检查 /d 的 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"
      ...
      

      【讨论】:

      • 谢谢!我想我想多了。