batch parameters: everything after %1
Solution 1
I am not sure if there is a direct command but you can always use a simple loop and shift to get the result in a variable. Something like:
@echo off set RESTVAR= shift :loop1 if "%1"=="" goto after_loop set RESTVAR=%RESTVAR% %1 shift goto loop1 :after_loop echo %RESTVAR%
Let me know if it helps!
Solution 2
There is a shorter solution (one-liner) utilizing the tokenization capabilities of for
loops:
:: all_but_first.bat
echo all: %*
for /f "tokens=1,* delims= " %%a in ("%*") do set ALL_BUT_FIRST=%%b
echo all but first: %ALL_BUT_FIRST%
output:
> all_but_first.bat foo bar baz
all: foo bar baz
all but first: bar baz
Footnote: Yes, this solution has issues. Same as pretty much anything written with batch files. It's 2021. Use Powershell or literally any other actual scripting language.
Solution 3
The following will work for args with ", =, ' '. Based on Dmitry Sokolov answer. Fixed issue when second arg is the same as first arg.
@echo off
echo %*
set _tail=%*
call set _tail=%%_tail:*%1=%%
echo %_tail%
Solution 4
The following will work for args with "
, =
, ' '
(as compared to @MaxTruxa answer)
echo %*
set _all=%*
call set _tail=%%_all:*%2=%%
set _tail=%2%_tail%
echo %_tail%
Test
> get_tail.cmd "first 1" --flag="other options" --verbose
"first 1" --flag="other options" --verbose
--flag="other options" --verbose
Solution 5
You can use SHIFT for this. It removes %1 and shifts all other arguments one lower. This script outputs all the arguments after %2 (so it outputs %3, %4...) until one of them is empty (so it's the last one):
@echo off
SHIFT
SHIFT
:loop
if "%1" == "" goto end
echo %1
SHIFT
goto loop
:end
EDIT: Removed example using %* as this doesn't work - %* always outputs all of the parameters
Comments
-
noamtm almost 2 years
Duplicate:
- Is there a way to indicate the last n parameters in a batch file?
- how to get batch file parameters from Nth position on?
Clarification: I knew of the looping approach - this worked even before Command Extensions; I was hoping for something fun and undocumented like %~*1 or whatever - just like those documented at http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/percent.mspx?mfr=true.
In a Windows batch file (with the so called "Command Extensions" on), %1 is the first argument, %2 is the second, etc. %* is all arguments concatenated.
My question: is there a way to get everything AFTER %2, for example?
I couldn't find such a thing, and it would be helpful for something I'm working on.
-
OscarRyz about 15 yearsJust like in sh? Great! +1 . Do you happen to know what's the powershell option?
-
Dijar about 15 yearsSorry, haven't used powershell yet.
-
Livven over 10 yearsThere's a small problem with this answer –
RESTVAR
will contain a leading space. Here's a slightly better version stackoverflow.com/a/761658/1488656 -
Chris Watts about 9 yearsFor 'all-but-n', replace
tokens=1
withtokens=n
. The remaining arguments will still be in%%b
-
FremyCompany about 9 yearsIn some cases, you may need to use !ALL_BUT_FIRST! instead of %ALL_BUT_FIRST% (for instance if you're inside some other loop); see stackoverflow.com/questions/12423238/…
-
Max Truxa about 9 yearsDon't forget to use
setlocal enabledelayedexpansion
if you are working with!var!
. -
EM0 over 8 yearsDoesn't work when a quoted parameter contains spaces, eg.
all_but_first.bat "first arg" "second arg"
-
Mr. Smythe almost 7 yearsI really want an ELI5 version of that CALL SET line.
-
Dmitry Sokolov almost 7 yearsAdvanced usage : CALLing internal commands. It works like
setlocal EnableDelayedExpansion
+set _tail=!_all:*%2=!
. -
Raman Zhylich almost 7 yearsIt will fail on this one: get_tail.cmd -s -s arg1
-
LINEMAN78 over 6 yearsDoesn't work when an argument contains an '=' ie debug=1 becomes debug 1.
-
David Gausmann over 6 yearsThis is the best solution for me, because the other solutions cropped my commas in the parameters.
-
cdlvcdlv about 6 yearsI think this is the only fail-safe answer and one of the simplest. It should be the accepted one.
-
HelloWorld over 5 yearsGood answer. But there is an error on statement. It worked when i change "%1" to "%~1".
-
binki over 5 yearsIt looks like you’re doing a string replacement of the first argument against the entire set of arguments. That will fail, like @RamanZhylich said, if your first argument happens to be substring of any of your subsequent arguments. This is bad in the same way as @MaxTruxa’s answer but almost worse because it isn’t as obviously wrong.
-
binki over 5 yearsI naively assumed this approach would work, realized that
%*
doesn’t update when usingSHIFT
, and then came to this SO question searching for a solution. Looks like you did the opposite :-p -
binki over 5 yearsPlease explain how this only replaces 1 instance of the string because the replacement portion of the string replace starts with
*
which makes it magical: gist.github.com/binki/a96bbf9a282616671ecd7386a9f17510 ss64.com/nt/syntax-replace.html -
bers almost 5 yearsFor me,
%_tail%
has a leading space. -
iki about 3 yearsNice one, has leading space (just know about it, should not be an issue), and returns
*=
for no args, so you better check if they are not emptyif not "%~1"=="" call set _tail=%%_tail:*%1=%%
-
iki about 3 yearsWorks for me even with spaces, treats all
=
and,
as arg separators -
iki about 3 yearsAlso treats all
=
and,
as arg separators for me -
iuzuz over 2 yearsFor what is the call keyword? Would simply "set.." without "call" not work?