1

I have been searching for an easy way to parse and interpret Windows command switches. I already know how to capture %*, %1, etc. but I can't seem to see any resource on how to parse compound flags such as in Git: -am.

I have been trying with something like:

echo(%1|findstr /r /c:"^-.*" >nul && (
  echo FOUND
  rem any commands can go here
) || (
  echo NOT FOUND
  rem any commands can go here
)

but to no avail. I thought the command line had easier syntax to deal with them. I want to handle scenarios like -a -m as well as -am.

I would also be curious how you code the batch file so that the sequence of the arguments is unrestricted.

user776686
  • 7,933
  • 14
  • 71
  • 124
  • It isn't easy in Batch files which is why most Windows script don't use them. It is only easy in Linux because there is a GNU app which helps. You may be able to find something similar for Windows. I don't know that app though. – krowe Mar 29 '14 at 19:14
  • BTW, that program is called `getopts` and I guess it is now a built-in but it used to be a separate app. – krowe Mar 29 '14 at 19:17
  • http://stackoverflow.com/questions/3494898/looking-for-unix-style-getopt-command-line-parsing-in-a-windows-dos-batch-file Maybe this will help, it shows how to parse without reguard to position of the arguments. – krowe Mar 29 '14 at 19:18

2 Answers2

2

This is a simple way to do that:

@echo off
setlocal EnableDelayedExpansion

rem Process parameters and set given switches
for %%a in (%*) do (
  set opt=%%a
  if "!opt:~0,1!" equ "-" set switch[%%a]=true
)

rem Use the given switches
if defined switch[-a] echo Switch -a given
if defined switch[-m] echo Switch -m given

EDIT: The modification below also allows to combine several switches, like in -am:

@echo off
setlocal EnableDelayedExpansion

rem Define possible switches
set switches=a m

rem Process parameters and set given switches
for %%a in (%*) do (
  set opt=%%a
  if "!opt:~0,1!" equ "-" (
      for %%b in (%switches%) do (
         if "!opt:%%b=!" neq "!opt!" set switch[-%%b]=true
      )
   )
)

rem Use the given switches
if defined switch[-a] echo Switch -a given
if defined switch[-m] echo Switch -m given
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • Thanks for that, it looked promising, but did not work actually. I messed around with `%*` changed to `%1` as well as with switches in form of `-am` and `-a -m`. Nothing happened :( – user776686 Mar 29 '14 at 19:42
  • That's much better. At this point of learning I'm more repeating other people's code than understanding, but now it works. Thank you. Even though it does not handle compund switches like `-am` I think it will suffice for the time being. Answer accepted and appreciated! – user776686 Mar 29 '14 at 19:57
  • PowerAacini! :) You rock. It's also a piece of a lesson. – user776686 Mar 29 '14 at 20:02
1

Complex options, flags, error on unknown, and order doesn't matter:

C:\DEV>usage /?
Usage: usage.cmd [/A word] [/B word] /c /d
Error: Unknown Option: /?

C:\DEV
>usage /b /B word /A "no way"
A="no way" B=word a= b=true

No nested for loops, using shift and goto.

@echo off

set FlagA=
set FlagB=

:Options
if "%1"=="/A" (
  set OptionA=%2
  shift
  shift
  goto Options
)
if "%1"=="/B" (
  set OptionB=%2
  shift
  shift
  goto Options
)
if "%1"=="/a" (
  set FlagA=true
  shift
  goto Options
)
if "%1"=="/b" (
  set FlagB=true
  shift
  goto Options
)
if "%1" NEQ "" (
  echo Usage: %~n0%~x0 [/A word] [/B word] /c /d
  echo Error: Unknown Option: %1
  goto :EOF
)

echo A=%OptionA% B=%OptionB% a=%FlagA% b=%FlagB%
B.McKee
  • 328
  • 1
  • 2
  • 15