[ACCEPTED]-Is there a way to indicate the last n parameters in a batch file?-cmd
%*
will always expand to all original parameters, sadly. But 5 you can use the following snippet of code 4 to build a variable containing all but the 3 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 2 ... I don't write these sort of things very 1 often :)
Should work, though.
Here's a one-line approach using the "for" command...
for /f "usebackq tokens=1*" %%i in (`echo %*`) DO @ set params=%%j
This 3 command assigns the 1st parameter to "i" and 2 the rest (denoted by '*') are assigned to 1 "j", which is then used to set the "params" variable.
Warning! this method has side-effect of expanding 7 wildcards, if there are «*»s or «?»s in 6 the arguments. If there is a wildcard but 5 no corresponding files, argument is skipped 4 (non-wildcard arguments stay as-is). If 3 arguments must stay intact, look for another 2 way.
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 1 may set skip var to any number of arguments.
Explaned:
(
@rem Starting block here, because it's read once and executed as one
@rem otherwise cmd.exe reads file line by line, which is waaay slower.
SETLOCAL ENABLEDELAYEDEXPANSION
SET skip=1
@rem if value contains unquoted non-paired parenthesis, SET varname=value
@rem confuses cmd.exe. SET "a=value" works better even if value has quotes.
FOR %%I IN (%*) DO (
IF !skip! LEQ 0 (
SET "params=!params! %%I"
@rem newline after SET to lower amount of pitfalls when arguments
@rem have unpaired quotes
) ELSE (
SET /A skip-=1
)
)
(
@rem get variables out of SETLOCAL block
@rem as whole block in parenthesis is read and expanded before executing,
@rem SET after ENDLOCAL in same block will set var to what it was before
@rem ENDLOCAL. All other envvars will be reset to state before SETLOCAL.
ENDLOCAL
SET "params=%params%"
)
@rem doing this outside of parenthesis block to avoid
@rem cmd.exe confusion if params contain unquoted closing round bracket
%CMD% %params%
You can actually just do this:
%*
If that is 4 the only thing on the line, then that expands 3 to having the first parameter be the command 2 executed, with all other parameters passed 1 to it. :)
I have improved Moshe Goren's answer because 1 it didn't seem to work for me:
set _input=%*
call set params=%%_input:%1 =%%
@echo %params%
Another way (almost the same as Alxander 11 Bird's) without executing ECHO in a subshell:
FOR /F "usebackq tokens=1*" %%I IN ('%*') DO SET params=%%J
so, line
%CMD% <WHAT DO I PUT HERE>
will 10 look like:
FOR /F "usebackq tokens=1*" %%I IN ('%*') DO %CMD% %%J
the problem is that if parameters 9 include quoted stings with spaces inside, cmd.exe 8 will parse them appropriately for using 7 as numbered arguments (%1), but FOR will 6 ignore the quotes. This specific case, it 5 will harm if first parameter includes a 4 space or more, which is quite possible, considering 3 first argument can be, for example, "C:\Program 2 Files\Internet Explorer\iexplore.exe".
So, here 1 will be another answer.
Although really the 'for' solution is superior 10 in a lot of circumstances, for something 9 simple I will frequently just save and shift 8 the other arguments away, then use %*
as usual 7 (practically the same strategy often works 6 for $*
or $@
in {,ba,da,k,*}sh
):
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 5 was long answered, but figured I'd drop 4 in my two cents as it was something I didn't 3 see, and because it was the answer I needed 2 when I finally happened across it a few 1 years back... and went "oh... duh." :)
I came across this question while I was 6 facing a similar problem, but I solved it 5 using a different approach. Instead of re-creating 4 the input line using a loop (as in the answer 3 by @Joey) I simply removed the first parameter 2 from the input string.
set _input=%*
set params=!_input:%1 =!
call OTHER_BATCH_FILE.cmd %params%
Of course, this assumes 1 that all the parameters are different.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.