Batch file 使用shift分析批内for循环中的输入参数

Batch file 使用shift分析批内for循环中的输入参数,batch-file,delayedvariableexpansion,Batch File,Delayedvariableexpansion,我正在尝试编写引导程序脚本,该脚本将解析参数并将其传递到框架中的其他应用程序中。下面这个最小的、可复制的示例,实际应用要复杂得多 该脚本的基本语法是 bootstrapper.bat type command "foo=1" "bar=test2" "baz=true" 它应该打电话来 type/command.bat 1 test2 true 有问题的片段是嵌套的for循环: setlocal enabledelayedexpansion rem this is actually fet

我正在尝试编写引导程序脚本,该脚本将解析参数并将其传递到框架中的其他应用程序中。下面这个最小的、可复制的示例,实际应用要复杂得多

该脚本的基本语法是

bootstrapper.bat type command "foo=1" "bar=test2" "baz=true"
它应该打电话来

type/command.bat 1 test2 true
有问题的片段是嵌套的for循环:

setlocal enabledelayedexpansion

rem this is actually fetched elsewhere in live app
set procedure_arguments_count=3

set arguments=
for /L %%L in (1,1,!procedure_arguments_count!) do (
    for /f "tokens=1,2 delims==" %%a in ("%~3") do set arguments=!arguments! %%b
    shift /3
)

echo !arguments!
问题是在执行此循环后,参数等于1,而不是1 test2 true

我相信内部循环预先填充了%%3,设置为foo=1,并忽略shift命令。我不能更改shift,因为我需要支持9+个参数,也不能出于其他原因删除外部循环

问题是-我可以延迟脚本参数的扩展吗?

您的问题是,即使在for循环执行之前,%x个参数也会被解析器用它们的初始值替换,因此移位在for循环中不会立即生效

一个简单的解决方法:将参数3…n分配给变量并处理:

setlocal enabledelayedexpansion
for /f "usebackq tokens=2,*" %%i in ('%*') do (
  for %%k in (%%j) do (
    for /f "tokens=2 delims==" %%a in ("%%~k") do (
      set "args=!args! %%~a"
    )
  )
)
set args
第一个为您获取参数3。。。 第二个用于处理每个剩余参数 第三个for从每个var=value字符串中获取值

或不带外部FOR/L回路


为什么不使用set arguments=%*?@jeb我需要放弃前两个参数并解析其余的参数
@ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion

rem this is actually fetched elsewhere in live app
set procedure_arguments_count=3
set arguments=
for /L %%L in (1,1,!procedure_arguments_count!) do (
    call set "aux=%%~3"
    for /f "tokens=1,2 delims==" %%a in ("!aux!") do set arguments=!arguments! %%b
    shift /3
)
echo !arguments!
@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion

set "procedure_arguments_count=3"
set "arguments="
set "ii=%procedure_arguments_count%"

:loopfor
  if [%3]==[]   goto :done
  if %ii% EQU 0 goto :done
  for /f "tokens=1,2 delims==" %%a in ("%~3") do set arguments=%arguments% %%b
  SHIFT /3
  set /A ii-=1
  goto :loopfor
:done

echo(%arguments%