是否有一种方法可以在批处理文件中显示最后的n个参数?

时间:2022-10-24 17:56:27

In the following example, I want to call a child batch file from a parent batch file and pass all of the remaining parameters to the child.

在下面的示例中,我希望从父批处理文件中调用子批处理文件,并将所有剩余的参数传递给该子。

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

Inside parent.cmd, I need to strip %1 off the list of parameters and only pass the remaining parameters to the child script.

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

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

I've investigated using SHIFT with %*, but that doesn't work. While SHIFT will move the positional parameters down by 1, %* still refers to the original parameters.

我已经调查过使用SHIFT + %*,但这行不通。当移位将位置参数向下移动1时,%*仍然是原始参数。

Anyone have any ideas? Should I just give up and install Linux?

谁有什么好主意吗?我应该放弃并安装Linux吗?

7 个解决方案

#1


64  

%* will always expand to all original parameters, sadly. But you can use the following snippet of code to build a variable containing all but the first parameter:

遗憾的是,%*会一直扩展到所有原始参数。但是,您可以使用下面的代码片段来构建一个变量,其中包含了第一个参数:

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

I think it can be done shorter, though ... I don't write these sort of things very often :)

我认为它可以缩短,尽管…我不经常写这些东西

Should work, though.

应该工作。

#2


15  

Here's a one-line approach using the "for" command...

这里有一个使用“for”命令的单行方法……

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

This command assigns the 1st parameter to "i" and the rest (denoted by '*') are assigned to "j", which is then used to set the "params" variable.

这个命令将第一个参数赋给“i”,其余的(用“*”表示)分配给“j”,然后用它来设置“params”变量。

#3


7  

the line

这条线

%CMD% <WHAT DO I PUT HERE>

shall be changed to:

应改为:

(
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%

of course, you may set Skip to any number of arguments.

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

#4


5  

You can actually just do this:

你可以这样做:

%*

If that is the only thing on the line, then that expands to having the first parameter be the command executed, with all other parameters passed to it. :)

如果这是行中唯一的东西,那么它将扩展到具有第一个参数的命令执行,并传递给它的所有其他参数。:)

#5


1  

Another way (almost the same as Alxander Bird's) without executing ECHO in a subshell:

另一种方法(几乎和Alxander Bird一样)没有在子shell中执行ECHO:

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

so, line

所以,行

%CMD% <WHAT DO I PUT HERE>

will look like:

的样子:

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

the problem is that if parameters include quoted stings with spaces inside, cmd.exe will parse them appropriately for using as numbered arguments (%1), but FOR will ignore the quotes. This specific case, it will harm if first parameter includes a space or more, which is quite possible, considering %CMD% can be, for example, "C:\Program Files\Internet Explorer\iexplore.exe".

问题是,如果参数包括引号内的空格,cmd。exe将对它们进行适当的解析,以作为编号的参数(%1),但是对于将忽略引号。这个特殊的情况,如果第一个参数包含一个空间或更多,这是很有可能的,这是很可能的,考虑到%CMD%可以,例如,“C:\程序文件\Internet Explorer\iexplore.exe”。

So, here will be another answer.

这是另一个答案。

#6


0  

Although really the 'for' solution is superior in a lot of circumstances, for something simple I will frequently just save and shift the other arguments away, then use %* as usual (practically the same strategy often works for $* or $@ in {,ba,da,k,*}sh):

尽管在很多情况下,“for”的解决方案都很好,但对于一些简单的事情,我通常只是将其他参数保存起来,然后将其他参数移走,然后使用%*(实际上,相同的策略通常在{、ba、da、k、*}中使用$*或$@):

example:

例子:

:: 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%

Anyhow, I saw the question was long answered, but figured I'd drop in my two cents as it was something I didn't see, and because it was the answer I needed when I finally happened across it a few years back... and went "oh... duh." :)

不管怎么说,我看到这个问题的答案很长,但我觉得我的两分钱会掉下来,因为这是我没看到的东西,因为这是我几年前在我身上遇到的那个答案。,“哦……咄。”:)

#7


0  

I came across this question while I was facing a similar problem, but I solved it using a different approach. Instead of re-creating the input line using a loop (as in the answer by @Joey) I simply removed the first parameter from the input string.

当我遇到类似的问题时,我遇到了这个问题,但我用另一种方法解决了这个问题。我没有使用循环重新创建输入行(如@Joey的答案),我只是从输入字符串中删除了第一个参数。

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

Of course, this assumes that all the parameters are different.

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

#1


64  

%* will always expand to all original parameters, sadly. But you can use the following snippet of code to build a variable containing all but the first parameter:

遗憾的是,%*会一直扩展到所有原始参数。但是,您可以使用下面的代码片段来构建一个变量,其中包含了第一个参数:

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

I think it can be done shorter, though ... I don't write these sort of things very often :)

我认为它可以缩短,尽管…我不经常写这些东西

Should work, though.

应该工作。

#2


15  

Here's a one-line approach using the "for" command...

这里有一个使用“for”命令的单行方法……

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

This command assigns the 1st parameter to "i" and the rest (denoted by '*') are assigned to "j", which is then used to set the "params" variable.

这个命令将第一个参数赋给“i”,其余的(用“*”表示)分配给“j”,然后用它来设置“params”变量。

#3


7  

the line

这条线

%CMD% <WHAT DO I PUT HERE>

shall be changed to:

应改为:

(
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%

of course, you may set Skip to any number of arguments.

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

#4


5  

You can actually just do this:

你可以这样做:

%*

If that is the only thing on the line, then that expands to having the first parameter be the command executed, with all other parameters passed to it. :)

如果这是行中唯一的东西,那么它将扩展到具有第一个参数的命令执行,并传递给它的所有其他参数。:)

#5


1  

Another way (almost the same as Alxander Bird's) without executing ECHO in a subshell:

另一种方法(几乎和Alxander Bird一样)没有在子shell中执行ECHO:

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

so, line

所以,行

%CMD% <WHAT DO I PUT HERE>

will look like:

的样子:

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

the problem is that if parameters include quoted stings with spaces inside, cmd.exe will parse them appropriately for using as numbered arguments (%1), but FOR will ignore the quotes. This specific case, it will harm if first parameter includes a space or more, which is quite possible, considering %CMD% can be, for example, "C:\Program Files\Internet Explorer\iexplore.exe".

问题是,如果参数包括引号内的空格,cmd。exe将对它们进行适当的解析,以作为编号的参数(%1),但是对于将忽略引号。这个特殊的情况,如果第一个参数包含一个空间或更多,这是很有可能的,这是很可能的,考虑到%CMD%可以,例如,“C:\程序文件\Internet Explorer\iexplore.exe”。

So, here will be another answer.

这是另一个答案。

#6


0  

Although really the 'for' solution is superior in a lot of circumstances, for something simple I will frequently just save and shift the other arguments away, then use %* as usual (practically the same strategy often works for $* or $@ in {,ba,da,k,*}sh):

尽管在很多情况下,“for”的解决方案都很好,但对于一些简单的事情,我通常只是将其他参数保存起来,然后将其他参数移走,然后使用%*(实际上,相同的策略通常在{、ba、da、k、*}中使用$*或$@):

example:

例子:

:: 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%

Anyhow, I saw the question was long answered, but figured I'd drop in my two cents as it was something I didn't see, and because it was the answer I needed when I finally happened across it a few years back... and went "oh... duh." :)

不管怎么说,我看到这个问题的答案很长,但我觉得我的两分钱会掉下来,因为这是我没看到的东西,因为这是我几年前在我身上遇到的那个答案。,“哦……咄。”:)

#7


0  

I came across this question while I was facing a similar problem, but I solved it using a different approach. Instead of re-creating the input line using a loop (as in the answer by @Joey) I simply removed the first parameter from the input string.

当我遇到类似的问题时,我遇到了这个问题,但我用另一种方法解决了这个问题。我没有使用循环重新创建输入行(如@Joey的答案),我只是从输入字符串中删除了第一个参数。

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

Of course, this assumes that all the parameters are different.

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