9

I'd like to check if an argument to a batch file is valid based on a list of strings.

For example:

IF %1 IN validArgument1, validArgument2, validArgument3 SET ARG=%1

This would set ARG to one of the valid arguments only if it matched. Ideally case insensitively.

justinhj
  • 11,147
  • 11
  • 58
  • 104

2 Answers2

6

You may also use the array approach:

setlocal EnableDelayedExpansion

set arg[1]=validArgument1
set arg[2]=validArgument2
set arg[3]=validArgument3

for /L %%i in (1,1,3) do if /I "%1" equ "!arg[%%i]!" SET "ARG=!arg[%%i]!"

In my opinion, this method is clearer and simpler to manage with multiple options. For example, you may create the array of valid arguments this way:

set i=0
for %%a in (validArgument1 validArgument2 validArgument3) do (
   set /A i+=1
   set arg[!i!]=%%a
)

Another possibility is to define a variable for each valid argument:

for %%a in (validArgument1 validArgument2 validArgument3) do set %%a=1

... and then just check the parameter this way:

if defined %1 (
   echo %1 is valid option...
   SET ARG=%1
)
dbenham
  • 127,446
  • 28
  • 251
  • 390
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • That's great thanks. I wish there was a more concise way to create Arrays but this will work perfectly. – justinhj Jun 28 '12 at 05:21
  • @justinhj - You need to be more careful when you edit someone elses post. You actually introduced an error. It works as originally written with `for /L %%i in (1,1,3)`, or as `for %%i in (1,2,3)`. But your edit of `for /L %%i in (1,2,3)` will not give the correct answer. I edited the answer back to how Aacini originally had it. – dbenham Jun 28 '12 at 15:17
  • 2
    Your second option needs to handle the case where %1 isn't provided. Adding a dummy prefix to each argument name would resolve it. – Kevin Jun 28 '12 at 17:52
  • @dbenham good spot. I would have tested it before correcting but I was on on my Macbook and didn't notice the /L which takes the following format: FOR /L %variable IN (start,step,end) DO command [command-parameters] – justinhj Jul 02 '12 at 02:01
5

A robust method is to use delayed expansion

setlocal enableDelayedExpansion
set "validArgs=;arg1;arg2;arg3;"
if "!validArgs:;%~1;=!" neq "!validArgs!" set ARG=%1

It can also be done using CALL along with normal expansion, but it is more likely to fail, depending on the value of the parameter.

set "validArgs=;arg1;arg2;arg3;"
call set "test=%%validArgs:;%~1;=%%"
if "%test%" neq "%validArgs%" set ARG=%1

Both techniques above have a limitation that no valid arg can contain = and args must not start with *.

You could also use the following brute force method as long as none of the valid args contain * ? , ; = or <space>

set "validArgs=arg1;arg2;arg3"
for %%A in (%validArgs%) if /i "%~1"=="%%A" set ARG=%1

You might want to have a look at this argument parser. You could adapt that code, or it might spark some ideas for your own unique strategy.

Community
  • 1
  • 1
dbenham
  • 127,446
  • 28
  • 251
  • 390