有没有办法将参数"按名称"(而不是按顺序)传递给批处理.bat文件?

Pou*_*uya 39 batch-file

我需要能够通过NAME(而不是按顺序)将参数传递给Windows批处理文件.我的目的是为最终用户提供以任何顺序传递参数的灵活性,批处理文件仍然可以处理它们.

一个让我的问题更清晰的例子:

在命令行中,用户执行以下操作: somebatchfile.bat originalFile.txt newFile.txt

在里面somebatchfile.bat有一个简单的语句将原始文件(第一个参数%1%)的内容复制到新文件(第二个参数%2%).它可以像下面的声明一样简单: copy %1% %2%

现在,如果用户以相反的顺序传递上述参数,结果将远非理想(实际上非​​常错误).

那么,有没有办法让用户按名称传递参数:例如somebatchfile.bat "SOURC=originalFile.txt" "TARGET=newFile.txt",脚本识别它们并在正确的位置使用'例如copy %SOURCE% %TARGET%

谢谢,

Dav*_*ger 24

是的,你可以做类似的事情虽然我不认为你可以使用"="作为一个标记分隔符.你可以使用说冒号":" somebatchfile.bat "SOURC:originalFile.txt" "TARGET:newFile.txt".以下是如何拆分令牌的示例:

@echo off

set foo=%1
echo input: %foo%

for /f "tokens=1,2 delims=:" %%a in ("%foo%") do set name=%%a & set val=%%b

echo name:  %name%
echo value: %val%
Run Code Online (Sandbox Code Playgroud)

运行它会产生这样的:

C:\>test.bat SOURC:originalFile.txt
input: SOURC:originalFile.txt
name:  SOURC
value: originalFile.txt
Run Code Online (Sandbox Code Playgroud)

[编辑]

好吧,也许昨晚我睡觉的时间太近了,但今天早上又看了,你可以这样做:

@echo off

set %1
set %2

echo source: %SOURCE%
echo target: %TARGET%
Run Code Online (Sandbox Code Playgroud)

这将产生这一点(请注意,我在命令行上反转了源和目标,以显示它们已正确设置和检索):

C:\>test.bat "TARGET=newFile.txt" "SOURCE=originalFile.txt"
source: originalFile.txt
target: newFile.txt
Run Code Online (Sandbox Code Playgroud)

请注意,%1和%2在之前进行评估,set因此将它们设置为环境变量.他们必须然而,可以在命令行上引用.

  • @Pouya:这个**批处理脚本**用一行代码解析一对`name&value`.这怎么可以*相当多的处理*?但后来,我发现你正在谈论拥有一个内置功能 - 好吧,不,批量脚本是一个非常有限的工具,微软已经(再一次)通过引入PowerShell间接承认. (3认同)

Fed*_*nis 8

聚会有点晚了:)这是我对管理"posix like"选项的建议.例如mybatchscript.bat -foo=foovalue -bar=barvalue -flag

:parseArgs
:: asks for the -foo argument and store the value in the variable FOO
call:getArgWithValue "-foo" "FOO" "%~1" "%~2" && shift && shift && goto :parseArgs

:: asks for the -bar argument and store the value in the variable BAR
call:getArgWithValue "-bar" "BAR" "%~1" "%~2" && shift && shift && goto :parseArgs

:: asks for the -flag argument. If exist set the variable FLAG to "TRUE"
call:getArgFlag "-flag" "FLAG" "%~1" && shift && goto :parseArgs


:: your code here ...
echo FOO: %FOO%
echo BAR: %BAR%
echo FLAG: %FLAG%

goto:eof
Run Code Online (Sandbox Code Playgroud)

..这里是完成这项工作的职能.您应该将它们放在同一个批处理文件中

:: =====================================================================
:: This function sets a variable from a cli arg with value
:: 1 cli argument name
:: 2 variable name
:: 3 current Argument Name
:: 4 current Argument Value
:getArgWithValue
if "%~3"=="%~1" (
  if "%~4"=="" (
    REM unset the variable if value is not provided
    set "%~2="
    exit /B 1
  )
  set "%~2=%~4"
  exit /B 0
)
exit /B 1
goto:eof



:: =====================================================================
:: This function sets a variable to value "TRUE" from a cli "flag" argument
:: 1 cli argument name
:: 2 variable name
:: 3 current Argument Name
:getArgFlag
if "%~3"=="%~1" (
  set "%~2=TRUE"
  exit /B 0
)
exit /B 1
goto:eof
Run Code Online (Sandbox Code Playgroud)

将文件另存为mybatchscript.bat并运行

mybatchscript.bat -bar=barvalue -foo=foovalue -flag
Run Code Online (Sandbox Code Playgroud)

你会得到:

FOO: foovalue
BAR: barvalue
FLAG: TRUE
Run Code Online (Sandbox Code Playgroud)


小智 7

其他方式我很喜欢:

set c=defaultC
set s=defaultS
set u=defaultU

:initial
if "%1"=="" goto done
echo              %1
set aux=%1
if "%aux:~0,1%"=="-" (
   set nome=%aux:~1,250%
) else (
   set "%nome%=%1"
   set nome=
)
shift
goto initial
:done

echo %c%
echo %s%
echo %u%
Run Code Online (Sandbox Code Playgroud)

运行以下命令:

arguments.bat -c users -u products
Run Code Online (Sandbox Code Playgroud)

将生成以下输出:

users
defaultS
products
Run Code Online (Sandbox Code Playgroud)

  • 带有空格的参数应该用双引号引起来 (2认同)

mmj*_*mmj 6

很老的问题,但我想我找到了一种将key=value参数传递给批处理文件的巧妙方法(没有外部依赖项)。您可以使用以下 MWE 测试该方法:

@echo off
chcp 65001

rem name this file test.bat and call it with something like:
rem test keyc=foo keyd=bar whatever keya=123 keyf=zzz

setlocal enabledelayedexpansion

set "map=%*"
call :gettoken keya var1
call :gettoken keyb var2
call :gettoken keyc var3

rem replace the following block with your real batch
rem ************************************************
echo:
echo Map is "%map%"
echo Variable var1 is "%var1%"
echo Variable var2 is "%var2%"
echo Variable var3 is "%var3%"
echo:
echo Done.
echo:
pause
rem ************************************************

goto :eof
:gettoken
call set "tmpvar=%%map:*%1=%%"
if "%tmpvar%"=="%map%" (set "%~2=") else (
for /f "tokens=1 delims= " %%a in ("%tmpvar%") do set tmpvar=%%a
set "%~2=!tmpvar:~1!"
)
exit /b
Run Code Online (Sandbox Code Playgroud)

方法相当:

  • 灵活,因为key=value参数可以与其他参数(例如文件名)混合,并且因为用于存储值的变量名称独立于键的名称
  • 可扩展,因为添加密钥很容易
  • 健壮,因为定义的键不允许传递的任何内容都将被忽略,并且未分配的键将获得一个空值(如果您愿意,您可以轻松更改此行为,以便它们获得类似nullundefined而不是空的值)

一个缺点是,如果一个键的名称是另一个键名称的一部分,它会变得混乱。因此,例如,如果您有一个类似 的键width,请不要定义类似 的键newwidth

享受。


Pio*_*trK 6

采取这次尝试(纯批次):

set PARAM_0=0
:parameters_parse

set parameter=%~1
if "%parameter%"=="" goto parameters_parse_done
if "%parameter:~0,1%"=="-" (
    set ARG_%parameter:~1%="%~2"
    shift
    shift
    goto parameters_parse
)
if "%parameter:~0,1%"=="/" (
    set ARG_%parameter:~1%="%~2"
    shift
    shift
    goto parameters_parse
)
set /a PARAM_0=%PARAM_0%+1
set PARAM_%PARAM_0%="%~1"
shift
goto parameters_parse

:parameters_parse_done

rem Insert your script here
Run Code Online (Sandbox Code Playgroud)

和一些测试:

call args.bat /bar="Hello World" Test1 -baz "Test test test" /foo=Test1 Test2

echo foo=%ARG_foo%
echo bar=%ARG_bar%
echo baz=%ARG_baz%
echo count=%PARAM_0%
echo 1=%PARAM_1%
echo 2=%PARAM_2%
Run Code Online (Sandbox Code Playgroud)

输出:

foo="Test1"
bar="Hello World"
baz="Test test test"
count=2
1="Test1"
2="Test2"
Run Code Online (Sandbox Code Playgroud)


Gau*_*aga 5

我希望看到读取提供给批处理程序的命名参数的可能性.例如 :

myBatch.bat arg1  arg2 
Run Code Online (Sandbox Code Playgroud)

读取参数可以如下完成:

%~1 would be arg1
%~2 would be arg2
Run Code Online (Sandbox Code Playgroud)

提供给批处理程序的上述参数很容易阅读,但每次执行它时,都必须维护顺序并记住arg1应该具有的内容.为了克服它,参数可以作为键:值格式提供.命令如下所示:

mybatch.bar key1:value1 key2:value2
Run Code Online (Sandbox Code Playgroud)

虽然没有直接的方法来解析这样的参数列表.我在批处理脚本中编写了以下嵌套for循环,它基本上将解析并创建环境变量,其中key1作为名称,并为其赋值value1.通过这种方式,您可以使用直接读取环境变量的方式读取所有提供的参数.

@echo off
FOR %%A IN (%*) DO (
   FOR /f "tokens=1,2 delims=:" %%G IN ("%%A") DO setLocal %%G=%%H
)
Run Code Online (Sandbox Code Playgroud)

之后,您可以使用%key1%format来读取所提供的所有参数.

HTH