有没有一种简单的方法来检测作为参数传递给批处理文件的参数的数量,然后用来for /L
循环遍历它们?
答案1
如何检测批处理文件的参数数量并循环遍历它们?
%*
批处理脚本中引用所有参数(例如 %1 %2 %3 %4 %5 ...%255)
您可以使用%*
它将所有命令行参数检索到批处理文件中。
要计算参数并循环,请for /L
参阅堆栈溢出回答批处理脚本 - 遍历参数经过腺泡:
@echo off setlocal enabledelayedexpansion set argCount=0 for %%x in (%*) do ( set /A argCount+=1 set "argVec[!argCount!]=%%~x" ) echo Number of processed arguments: %argCount% for /L %%i in (1,1,%argCount%) do echo %%i- "!argVec[%%i]!"
进一步阅读
- Windows CMD 命令行的 AZ 索引- 与 Windows cmd 行相关的所有事物的绝佳参考。
- 为了- 有条件地执行命令多次。
- 参数- 命令行参数(或参数)是传递到批处理脚本的任何值:
答案2
总体而言,@DavidPostill 的答案是正确的。/?
但它看不到开关(可能还有其他一些开关)。如果您想看到这些,那么您可以使用:for %%x in ("%*") do (
而不是for %%x in (%*) do (
。问题是这个版本看不到引号中的任何内容。如果您想要一个可以同时执行这两项操作的版本,那么这里有一个明显不那么简单的答案:
@set @junk=1 /*
@ECHO OFF
:: Do not changes the above two lines. They are required in order to make the
:: JScript below work.
:: In order to get the parameter count from WSH we will call this script
:: three times in three different ways. The first time, it'll run the code in this
:: section just as any normal BATCH script would. At the end of this section, it'll
:: call cscript.exe in order to run the JScript portion below.
:: The final call will be the same call as was originally requested but with the
:: difference of the first parameter being the word redux (if that is a possible
:: valid value for your script then you'll want to change it here and in the
:: JScript below as well).
IF "%1" == "redux" @GOTO :CLOSINGTIME
:: The next step passes this script to get the WSH command line executable for
:: further processing.
cscript //nologo //E:jscript %~f0 %*
:: Exit the initial call to this script.
GOTO:EOF */
// We are now in the second iteration of the call. Here we are using JScript
// instead of batch because WSH is much better at counting it's parameters.
var args=WScript.Arguments,
sh=WScript.CreateObject("WScript.Shell"),
cmd="%comspec% /k " + WScript.ScriptFullName + ' redux ' + args.length;
for(var i=0, j=args.length; i<j; i++)
cmd+=' "' + args(i) + '"';
// sh.Popup("The generated command line is:\n "+cmd);
var exec=sh.Exec(cmd);
while(!exec.StdOut.AtEndOfStream)
WScript.Echo(exec.StdOut.ReadLine());
// Leave the script now. Remember that the entire script needs to be parsable by
// WSH so be sure that anything after this line is in the comment below.
WScript.Quit(0);
/* This line is here to hide the rest of the file from WSH.
========================================================================
:CLOSINGTIME
:: Now we've called this script 3 times (once manually and now twice more just
:: to get back here knowing the correct argument count. We've added that value
:: to the command line so lets remove that cruft before we call this done.
:: Remove the static, redux, parameter
SHIFT
:: Save the argument count.
SET ARGC=%1
:: Remove ARGC parameter
SHIFT
:: Now you are ready to use your batch code. The variable %ARGC% contains the
:: argument count of the original call.
:: ******************************
:: ** START OF YOUR BATCH CODE **
:: ******************************
ECHO Fancy JScript count: %ARGC%
ECHO.
:: ****************************
:: ** END OF YOUR BATCH CODE **
:: ****************************
:: This is needed in order to let the JScript portion know that output has ended.
EXIT
:: ========================================================================
:: This line will hide everything in your second BATCH portion from WSH. */
不幸的是,由于我们必须从 WSH 内部执行文件的方式,这也不是完美的答案,最终脚本中的 StdErr 和 StdOut 都损坏了。在某些情况下,您可以通过2&>1
在第二个批处理调用结束时使用来修复 StdErr:var exec=sh.Exec(cmd+" 2&>1");
不过,StdIn 需要作为每个脚本的特殊情况来处理。