2009-04-17 58 views
34

在以下示例中,我想从父批处理文件中调用一个子批处理文件,并将所有其余参数传递给子处理。有没有办法指出批处理文件中的最后n个参数?

C:\> parent.cmd child1 foo bar 
C:\> parent.cmd child2 baz zoop 
C:\> parent.cmd child3 a b c d e f g h i j k l m n o p q r s t u v w x y z 

在parent.cmd中,我需要从参数列表中去除%1,并且只将其余参数传递给子脚本。

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

我调查了使用SHIFT与%*,但这并不起作用。虽然SHIFT会将位置参数向下移动1,但%*仍然是指原始参数。

任何人有任何想法?我应该放弃并安装Linux吗?可悲的是,

+0

重复? http://stackoverflow.com/questions/382587/how-to-get-batch-file-parameters-from-nth-position-on – 2009-04-17 18:54:54

+0

这个问题回答了代码,没有工作。我在我的问题中加入了一些陈述来帮助澄清,而且看起来我从Johannes得到了一个确凿的答案。 – Dave 2009-04-17 23:29:09

+0

哦,顺便说一句,当所有的男士从其他批次调用批次时都使用call。否则调用批处理文件将不会在被调用批处理退出后继续运行。 (可能在这里可能没有关系,只是一些最佳实践:-)) – Joey 2009-04-18 06:44:49

回答

62

%*将始终扩展到所有原始参数。但是你可以使用下面的代码片段建立包含所有变量,但第一个参数:

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

,我认为这是可以做到更短,不过......我不经常写这些样的东西:)

应该工作,虽然。

+0

正如Tbee所说,如果你在剩下的参数中有'=',这是行不通的。似乎解决这个问题的唯一真正方法是编写一个程序来正确地提取您的参数 - cmd shell太简陋了。 – 2011-08-20 00:08:42

+3

如果您在参数中进行了分配,则此方法失败,例如“A = B”。然后你会得到两个单独的参数“a”和“b”,失去了=。 – Tbee 2010-09-03 09:22:07

+2

在这种情况下,引用该论点。 'cmd'认为还有几个字符也是参数分隔符,比如';'或','。 – Joey 2011-08-20 12:11:20

14

下面是使用的“for”命令

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

该命令给第一参数“i”和其余被分配给(由“*”表示)的一行的方法“ j“,然后用它来设置”params“变量。

+0

当第一个参数包含一个空格(引用)时,例如''“第一个参数”第二个第三'将参数设置为'参数“第二个三分之一' – EM0 2016-04-13 09:12:54

5

可以真正做到这一点:

%* 

如果是这样就行了嘛,那么扩展到具有第一个参数执行的命令,以传递给它的所有其他参数。 :)

1

的另一种方式,而不在子shell执行ECHO(几乎一样Alxander鸟):

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),但FOR将忽略引号。这个特殊情况下,如果第一个参数包含一个空格或更多空间,这很可能会损害%CMD%,例如“C:\ Program Files \ Internet Explorer \ iexplore.exe”。

所以,这里会有另一个答案。

7

%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% 
当然

,可以设定跳转到任意数量的参数。

0

尽管真正的“对”的解决方案是在很多情况下卓越,简单的东西,我会经常只保存和转移等参数了,然后用%*像往常一样(实际上是相同的策略,往往适用于$*[email protected]{,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% 

无论如何,我看到了问题是长回答,但想我会博士因为这是我没看见的东西,因为这是我几年前终于碰到它时所需要的答案......然后“去......哦”。 :)

+1

移位不会影响% *因此,这将所有*原始参数传递给%run_me%,包括%1和%2。正如接受的答案所述,“%*将始终扩展到所有原始参数,令人伤心。 – Naaff 2016-01-12 18:23:54

0

我遇到了这个问题,虽然我面临类似的问题,但我解决了它使用不同的方法。 我只是从输入字符串中删除第一个参数,而不是使用循环重新创建输入行(如在@Joey的答案中)。

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

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

相关问题