Abhi Kumar Sahu
Abhi Kumar Sahu

Reputation: 77

How to parse command line arguments with SWITCH in BATCH file

We are trying to make a switch statement which is parsing command line argument in a batch file.

mybatch.bat -a 10 -b name -c India --zipcode 20

Only -a, -b, -c are parsing parameter (which is starts with -).

Our code will be like:

for %%x in (%*) do (
     switch(%%x) (
          case a:
                 SET first_number=%arg%
                 break
          case b:
                 SET name=%arg%
          case c:
                 for %%x in (%*) do (
                       SET place =%place% %arg%
                  )
          default:
                  echo wrong parameter
           )

Upvotes: 4

Views: 8340

Answers (4)

pps
pps

Reputation: 58

The solution by Aacini is very smart and solves exactly what was requested, kudos!

I had an extended requirement: a mix of switches with values and switches without values being the parameters in arbitrary order. For instance, for recursive processing one would just want to enter -r, not -r followed by a value. With Aacini's solution, if a switch directly follows another switch the second switch is being eaten as the value for the first switch.

So, I enhanced Aacini's solution. In my solution, if a switch -x is presented without a value as the input argument, a variable option-x is created, set to 1.

set "option="
for %%a in (%*) do (
    set arg=%%a
    if not defined option (
        if "!arg:~0,1!" equ "-" (
            set "option=!arg!"
            set "option!arg!=1"
        )
    ) else (
        if "!arg:~0,1!" neq "-" (
            set "option!option!=!arg!"
            set "option="
        ) else (
            set "option!option!=1"
            set "option=!arg!"
        )
    )
)
if defined option (
    set "option!option!=1"
    set "option="
)

So, for example for

test -r -scale 100 

two variables will be defined:

option-r=1
option-scale=100 

Upvotes: 0

Scott C
Scott C

Reputation: 1660

Normally you try to keep things simple and have a set order for the parameters. To handle parameters in any, random order is a lot more effort than just knowing that %1 = number, %2 = name and %3 onwards = place.

That said, here's an attempt at a solution. I'm ignoring --params in the place section, just joining the values together.

@echo off
setlocal

:loop
if x%1 equ x goto done
set param=%1
if %param:~0,1% equ - goto checkParam
:paramError
echo Parameter error: %1 

:next
shift /1
goto loop

:checkParam
if "%1" equ "-a" goto A
if "%1" equ "-b" goto B
if "%1" equ "-c" goto C
goto paramError

:A
    shift /1
    set first_number=%1
    goto next

:B
    shift /1
    set name=%1
    goto next

:C
    set place=
:GetPlaces
    shift /1
    set param=%1
    if not defined param goto donePlaces
    if %param:~0,2% equ -- (
        shift /1
        goto processPlace
    )
    if %param:~0,1% equ - goto donePlaces
:processPlace
echo.%place%
    if x%1 neq x (
        set place=%place% %1
        goto GetPlaces
    )
:donePlaces
    rem remove leading space
    if defined place set place=%place:~1%
    goto loop



:done

echo num=%first_number%     name=%name%     place=%place%

Upvotes: 8

Aacini
Aacini

Reputation: 67216

The Batch file below parses all arguments that start with - and creates a series of variables that start with "option" and the names and values of all options given:

@echo off
setlocal EnableDelayedExpansion

set "option="
for %%a in (%*) do (
   if not defined option (
      set arg=%%a
      if "!arg:~0,1!" equ "-" set "option=!arg!"
   ) else (
      set "option!option!=%%a"
      set "option="
   )
)

SET option

For example:

>test -a 10 -b name -c India --zipcode 20
option--zipcode=20
option-a=10
option-b=name
option-c=India

This way, you need to make no changes in the parsing code if you want to add/change/delete any option, just use the value of the option you want. For example:

if defined option-x (
   echo Option -x given: "%option-x%"
) else (
   echo Option -x not given
)

Upvotes: 15

npocmaka
npocmaka

Reputation: 57262

there's no switch command in batch.You need to workaround this with if statements:

@echo off
setlocal enableDelayedExpansion
for /l %%a in (1,2,6) do (
    set /a next=%%a+1

    set param=%%a

    call set _param=%%!param!
    call set _next=%%!next!

    rem echo -!next! -!_next! #!_param! #%%a 

    if "!_param!" equ "-a" (
        set first_number=!_next!
    )

    if "!_param!" equ "-b" (
        call set name=!_next!
    )

    if "!_param!" equ "-c" (
        set place=!_next!
    )

)

for %%a in (place first_number name) do (
    if not defined %%a set wrong_parameter=1
)

if defined wrong_parameter (
    echo wrong parameter
)

echo %place% %first_number% %name%

Upvotes: 1

Related Questions