I wouldn't use the for-loop to read arguments. As LinuxDisciple mentioned it, don't compare batch to bash or csh too quickly. For eg. it isn't easy to create or access arrays or hashes in batch (if interested I added some links at the end of my answer where they explain how it is possible). If you really want to use a for-loop, the use of the state variable is probably your best shot (see Klitos Kyriacou's answer).
I would use the traditional labels and goto instead in batch
@echo off
SetLocal EnableDelayedExpansion
:check_args
REM Check if arguments left
IF "%~1%" == "" goto :EndArgs
IF "%~1" == "abc" (
REM next argument is %2
set var=%~2
REM Don't forget extra shift because you already handled next argument too
shift
echo I just saw you gave "abc", I set var to !var!
) ELSE (
echo It's just a normal argument: "%~1"
)
shift
goto :check_args
:EndArgs
EndLocal
exit
As LinuxDisciple mentionned also, don't surround the "=" with spaces when assigning variables, it may give unexpected results(variable names with trailing spaces, values with heading space, ...). The above code will result in stuff like (script is called argum.bat):
>argum abc blabla def
I just saw you gave "abc", I set var to "blabla"
It's just a normal argument: def
>argum "just random things" abc "this is more serious"
It's just a normal argument: "just random things"
I just saw you gave "abc", I set var to "this is more serious"
Here is a link to delayed expansion. It is needed in this case because the cmd-parser will load IF-clauses and FOR-loops as one single command (as if it was written on one line). You can't create a variable and read from it in the same command unless you use delayed expansion. It also explains why I use !var!
instead of %var%
.
I also used %~1
instead of %1
to remove the surrounding quotation marks ("). This link has some other "tricks" you can use to manipulate arguments and for-loop variables
Off course if you want to do some more complex things with your arguments this isn't a good option because of the size the if-else clauses will take. You'll have to use some other way to treat your arguments like the one I used when I asked this question (please read the answer as well) or the method proposed as answer in this question (also posted as link in an answer to my question as well).
Good luck!
PS As promissed, the links to the array solutions in batch:
- In this tutorial you'll see why it's "tricky" to use the normal array indexing
- Another way is to list all elements in a string, separate them with a separator (whitespace is mostly used) and use the
for /f
-loop with the separator as delimiter to iterate (as what you did). Problem here is that you'll have to use extra variables to acces other array elements than the one you're at during the iteration.