Batch file 是否有传递参数的方法;“按名称”;(而不是按订单)添加到batch.bat文件?
我需要能够通过名称(而不是顺序)向windows批处理文件传递参数。我在这里的目的是给最终用户以任意顺序传递参数的灵活性,批处理文件应该仍然能够处理它们 让我的问题更清楚的一个例子是: 在命令行中,用户执行以下操作:Batch file 是否有传递参数的方法;“按名称”;(而不是按订单)添加到batch.bat文件?,batch-file,Batch File,我需要能够通过名称(而不是顺序)向windows批处理文件传递参数。我在这里的目的是给最终用户以任意顺序传递参数的灵活性,批处理文件应该仍然能够处理它们 让我的问题更清楚的一个例子是: 在命令行中,用户执行以下操作: somebatchfile.bat originalFile.txt newFile.txt 在somebatchfile.bat内部,有一条简单的语句可以将原始文件(第一个参数%1%)的内容复制到新文件(第二个参数%2%)。它可以像以下语句一样简单: 复制%1%%2% 现在,如果
somebatchfile.bat originalFile.txt newFile.txt
在somebatchfile.bat内部,有一条简单的语句可以将原始文件(第一个参数%1%)的内容复制到新文件(第二个参数%2%)。它可以像以下语句一样简单:
复制%1%%2%
现在,如果用户以相反的顺序传递上述参数,结果将远远不理想(事实上是非常错误的)
那么,有没有一种方法可以让用户按名称传递参数:例如,somebatchfile.bat“SOURC=originalFile.txt”“TARGET=newFile.txt”
,让脚本识别它们并在正确的位置使用它们,例如,copy%SOURCE%%TARGET%
谢谢,是的,你可以这样做,尽管我认为你不能用“=”作为标记分隔符。您可以使用冒号“:”,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%
运行此命令将产生以下结果:
C:\>test.bat SOURC:originalFile.txt
input: SOURC:originalFile.txt
name: SOURC
value: originalFile.txt
[编辑]
好吧,也许昨晚我离睡觉时间太近了,但今天早上再看一遍,你可以这样做:
@echo off
set %1
set %2
echo source: %SOURCE%
echo target: %TARGET%
这将产生以下结果(请注意,我在命令行上反转了源和目标,以显示它们已正确设置和检索):
请注意,在设置
之前对%1和%2进行求值,因此它们确实被设置为环境变量。但是,必须在命令行中引用它们。我认为您正在寻找Windows批处理脚本中的getopt支持,不幸的是,这些脚本并不完整。最接近你可能得到的是使用。这样,您就可以使用以下命令执行脚本:
somebatchfile.bat /SOURC:originalFile.txt /TARGET:newFile.txt
arguments.bat -c users -u products
代码:
我想看看读取提供给批处理程序的命名参数的可能性。例如:
myBatch.bat arg1 arg2
读取参数的步骤如下:
%~1 would be arg1
%~2 would be arg2
上面提供给批处理程序的参数很容易阅读,但每次执行它时,您都必须保持顺序并记住arg1应该有什么。为了克服这个问题,参数可以作为key:value格式提供。命令如下所示:
mybatch.bar key1:value1 key2:value2
虽然没有直接的方法来解析这样的参数列表。我在批处理脚本中编写了以下嵌套for循环,它将基本上解析和创建以key1为名称的环境变量,并为其分配value1。通过这种方式,您可以读取使用直接读取环境变量的方式提供的所有参数
@echo off
FOR %%A IN (%*) DO (
FOR /f "tokens=1,2 delims=:" %%G IN ("%%A") DO setLocal %%G=%%H
)
之后,您可以使用%key1%
格式读取提供的所有参数
HTH另一方面,我非常喜欢:
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%
运行以下命令:
somebatchfile.bat /SOURC:originalFile.txt /TARGET:newFile.txt
arguments.bat -c users -u products
将生成以下输出:
users
defaultS
products
此代码检查所有参数,去掉所有外部引号,如果存在等号,则将变量设置为值
像这样使用它:
yourbatch.bat "foo=bar" "foo2=bar2"
基于此答案:,并针对该方晚了一点的编辑尝试进行了编辑:)这是我对管理“类似posix”选项的建议。
例如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
…这里是完成这项工作的功能。您应该将它们放在同一批处理文件中
:: =====================================================================
:: 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
将文件另存为mybatchscript.bat
并运行
mybatchscript.bat -bar=barvalue -foo=foovalue -flag
您将获得:
FOO: foovalue
BAR: barvalue
FLAG: TRUE
非常老的问题,但我认为我找到了一种将
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
方法非常简单:
- 灵活,因为
参数可以与其他参数(例如文件名)混合,并且用于存储值的变量的名称独立于键的名称key=value
- 可扩展,因为很容易添加密钥
- 健壮,因为忽略已定义的键不允许传递的任何内容,而未分配的键会得到一个空值(如果需要,您可以轻松更改此行为,使它们得到类似于
或null
未定义的值,而不是空值)
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%
产出:
foo="Test1"
bar="Hello World"
baz="Test test test"
count=2
1="Test1"
2="Test2"
我的天哪,我的人民;你想得太多了!:)
OP的CMD
arg的格式都是“[VarName]=[Something]”
所以第一行可以是%%\uIn(%%*)DO SET“%%~\u”
或者用好看的代码
对于(%*)中的%%\u,请设置“%%~\u”
也就是说,这里有一个更完整的脚本示例,您可以将所有脚本放在:Main
函数中
@(Setlocal)
回音
对于(%*)中的%%\u,请设置“%%~\u”
)
电话:Main
(完)
退出(B)
:Main
你的代码在这里。
你的代码在这里。
你的代码在这里。
你的代码在这里。
后藤:EOF
谢谢Dave,但您的解决方案涉及批处理文件内部的“相当多的处理”。然而,我们需要的是一种“内置”功能,它可以自动使用传递的参数填充内部变量(在用户脚本中)。例如:按照惯例,他们知道如果他们传递这样一个参数:“SOURC:originalFile.txt”,那么他们的内部变量%name%和%val%将自动获得正确的值。@Pouya:此批处理脚本仅用一行代码解析name&value
对。这怎么可能是相当多的处理呢?但是,我看到你说的是拥有内置功能——不,批处理脚本是一个非常有限的工具,微软(再次)通过引入PowerShell间接承认了这一点
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%
foo="Test1"
bar="Hello World"
baz="Test test test"
count=2
1="Test1"
2="Test2"