有没有办法指出batch file中的最后n个参数?

在以下示例中,我想从父batch file中调用一个子batch file,并将所有其余parameter passing给子处理。

C:\> parent.cmd child1 foo bar C:\> parent.cmd child2 baz zoop C:\> parent.cmd child3 abcdefghijklmnopqrstu vwxyz 

在parent.cmd里面,我需要从参数列表中去掉%1,并且只把剩下的参数传给子脚本。

 set CMD=%1 %CMD% <WHAT DO I PUT HERE> 

我已经调查使用SHIFT与%*,但不起作用。 当SHIFT将位置参数向下移动1时,%*仍然是指原始参数。

有人有主意吗? 我应该放弃并安装Linux?

不幸的是, %*将始终扩展到所有原始参数。 但是,您可以使用下面的代码片段来构build一个包含除第一个参数外的所有variables:

 rem throw the first parameter away shift set params=%1 :loop shift if [%1]==[] goto afterloop set params=%params% %1 goto loop :afterloop 

我认为这可以做得更短,虽然…我不会经常写这些东西:)

应该工作,但。

以下是使用“for”命令的单行方法…

 for /f "usebackq tokens=1*" %%i in (`echo %*`) DO @ set params=%%j 

该命令将第一个参数赋值给“i”,其余的(用“*”表示)赋值给“j”,然后用于设置“params”variables。

线

 %CMD% <WHAT DO I PUT HERE> 

应改为:

 ( SETLOCAL ENABLEDELAYEDEXPANSION SET Skip=1 FOR %%I IN (%*) DO IF !Skip! LEQ 0 ( SET params=!params! %%I ) ELSE SET /A Skip-=1 ) ( ENDLOCAL SET params=%params% ) %CMD% %params% 

当然,你可以设置跳转到任意数量的参数。

你其实可以做到这一点:

 %* 

如果这是唯一的行,那么扩展到第一个参数执行命令,所有其他parameter passing给它。 🙂

另一种方式(几乎像阿尔克桑德·伯德一样)没有在子shell中执行ECHO:

 FOR /F "usebackq tokens=1*" %%I IN ('%*') DO SET params=%%J 

所以,行

 %CMD% <WHAT DO I PUT HERE> 

会看起来像:

 FOR /F "usebackq tokens=1*" %%I IN ('%*') DO %CMD% %%J 

问题是,如果参数包含内部带空格的引号,cmd.exe会使用编号参数(%1)适当地parsing它们,但是FOR将忽略引号。 这种情况下,如果第一个参数包含一个空格或更多的空间,这将是非常可能的,考虑到%CMD%可以是例如“C:\ Program Files \ Internet Explorer \ iexplore.exe”。

所以,这里将是另一个答案。

尽pipe在很多情况下,'for'解决scheme是优越的,但是对于简单的事情,我会经常保存并转移其他参数,然后像往常一样使用%* (几乎相同的策略通常适用于$*$@ {,ba,da,k,*}sh ):

例:

 :: run_and_time_me.cmd - run a command with the arguments passed, while also piping :: the output through a second passed-in executable @echo off set run_me=%1 set pipe_to_me=%2 shift shift :: or :: set run_me=%1 :: shift :: set pipe_to_me=%1 :: shift %run_me% %* | %pipe_to_me% 

无论如何,我看到这个问题已经得到了长时间的回答,但是我认为我会下降两分钱,因为这是我没有看到的,因为这是我几年前偶然发现的问题所需要的答案。去了“哦…呃。” 🙂

我在遇到类似的问题时遇到了这个问题,但我用另一种方法解决了这个问题。 而不是使用循环重新创buildinput行(如@Joey的答案),我只是从inputstring中删除第一个参数。

 set _input=%* set params=!_input:%1 =! call OTHER_BATCH_FILE.cmd %params% 

当然,这是假定所有的参数是不同的。