IF: [ ] vs " "

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
ldoodle
Posts: 18
Joined: 26 Sep 2015 04:01

IF: [ ] vs " "

#1 Post by ldoodle » 28 Sep 2015 10:03

Hey,

Why does this work:

Code: Select all

if /i "!arg:~0,2!"=="/t" (
   rem Do this...
)


but this doesn't:

Code: Select all

if /i [!arg:~0,2!] equ [/t] (
   rem Do this...
)


It results in:

Code: Select all

2!] was unexpected at this time.


Square brackets work fine for other manipulation though:

Code: Select all

if [!arg:~2!] equ [/t]...


If I escape the comma, it then works. So just wondering why the comma needs escaping in enclosed brackets, whereas in double quotes it doesn't.

Thanks!

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: IF: [ ] vs " "

#2 Post by Squashman » 28 Sep 2015 10:37

Are you trying to validate command line arguments passed to the batch file?

ldoodle
Posts: 18
Joined: 26 Sep 2015 04:01

Re: IF: [ ] vs " "

#3 Post by ldoodle » 28 Sep 2015 15:32

Not necessarily validate them, as such, but break them up.

So someone can enter /T:<path>, hence grabbing the first 2 chars, so I check for /T then take the rest of the string as another value, so <path>:

Code: Select all

REM Check for arguments
for %%x in (%*) do (
   set arg=%%x
   if /i [!arg!] equ [/l] (
      set logtofile=true
   ) else if /i [!arg!] equ [/v] (
      set logtoscrn=true
   ) else if /i [!arg!] equ [/d] (
      if exist %logfile% del /q %logfile%
      set logtofile=true
   ) else if /i [!arg!] equ [/s] (
      set summary=true
   ) else if /i [!arg:~0^,2!] equ [/t] (
      set toolsdir=!arg:~3!
   ) else (
      echo.!arg! | find /i ":\">nul
      if errorlevel 1 (
         goto usage
      ) else (
         set folder=!arg!
      )
   )
)

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: IF: [ ] vs " "

#4 Post by Squashman » 28 Sep 2015 19:16

Why not use %1, %2, etc....

ldoodle
Posts: 18
Joined: 26 Sep 2015 04:01

Re: IF: [ ] vs " "

#5 Post by ldoodle » 29 Sep 2015 02:52

I wanted to allow different positions for the arguments.

If I was explicitly using %1 %2 they'd always have to be in the same position.

So command.cmd /t /s /v would behave differently to command.cmd /s /v /t as the argument values would change.

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: IF: [ ] vs " "

#6 Post by dbenham » 29 Sep 2015 05:43

It fails because the comma is a token delimiter that must be either quoted or escaped if used within a delayed expansion expression as part of an IF statement. The full explanation requires a full understanding of the batch parser. But in short, the IF command is one of 2 commands that get a special parsing pass that is sensitive to token delimiters (space, colon, semicolon, equal sign, 0xFF). They are not a problem when using normal percent expansion because that occurs before the IF special parsing. But the delayed expansion occurs after the IF special parsing, so the token delimiters must either be escaped or quoted.

The square brackets have no special meaning - they simply guarantee the expression is not empty, which is needed when you use normal expansion. You could use any single character at the beginning or end of each side. But with delayed expansion, the IF parser sees the expression before expansion, so it is guaranteed to be non-empty, and the extra characters are not needed.

Either of the following will work:

Code: Select all

if "!arg:~0,2!" equ "/t"
if !arg:~0^,2! equ /t


If you are looking to implement named parameters for a batch script, then you should have a look at http://stackoverflow.com/a/8162578/1012053


Dave Benham

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: IF: [ ] vs " "

#7 Post by Squashman » 29 Sep 2015 06:19

ldoodle wrote:If I was explicitly using %1 %2 they'd always have to be in the same position.

Well I disagree with that.

ldoodle
Posts: 18
Joined: 26 Sep 2015 04:01

Re: IF: [ ] vs " "

#8 Post by ldoodle » 01 Oct 2015 13:48

Squashman wrote:
ldoodle wrote:If I was explicitly using %1 %2 they'd always have to be in the same position.

Well I disagree with that.


This is what I'm currently doing:

Code: Select all

for %%x in (%*) do (
   set arg=%%~x
   set /a a_count+=1
   if /i [!arg:~0^,2!] equ [/d] (
      if [!arg:~3!] neq [] for /f "delims=" %%x in (!arg:~3!) do set "targetdir=%%~fx"
   ) else if /i [!arg:~0^,2!] equ [/o] (
      set overwrite=true
   ) else if /i [!arg:~0^,2!] equ [/l] (
      set logtofile=true
      if [!arg:~3!] neq [] for /f "delims=" %%x in (!arg:~3!) do set "logdir=%%~fx"
   ) else if /i [!arg!] equ [/x] (
      set logtofile=true
      set dellogfile=true
   ) else if /i [!arg!] equ [/v] (
      set logtoscrn=true
   ) else if /i [!arg:~0^,2!] equ [/t] (
      if [!arg:~3!] neq [] for /f "delims=" %%x in (!arg:~3!) do set "toolsdir=%%~fx"
   ) else if /i [!arg:~0^,2!] equ [/c] (
      set createlogdir=true
   ) else if /i [!arg!] equ [/s] (
      set summary=true
   ) else if /i [!arg!] equ [/p] (
      set defaultargs=true
   ) else if /i [!arg!] equ [/y] (
      if exist %defargsfile% del /q %defargsfile%
   ) else (
      goto usage
   )
   shift /1
)


If it can be improved, great!

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: IF: [ ] vs " "

#9 Post by Aacini » 01 Oct 2015 18:59

Like this one, perhaps?

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem Define the array of switches
for %%x in ("d=targetdir" "o=overwrite"    "l=logtofile" "x=dellogfile"  "v=logtoscrn"
            "t=toolsdir"  "c=createlogdir" "s=summary"   "p=defaultargs" "y=deldefargsfile") do (
   for /F "tokens=1,2 delims==" %%a in (%%x) do (
      set "switch[/%%a]=%%b"
   )
)

rem Check parameters and set switches given
for %%x in (%*) do for /F "tokens=1* delims=:" %%a in ("%%~x") do (
   if not defined switch[%%a] (
      set "badSwitch=%%a"
      goto usage
   ) else if "%%~b" equ "" (
      set "!switch[%%a]!=true"
   ) else (
      set "!switch[%%a]!=%%~b"
   )
)

rem Process special cases
if defined dellogfile if not defined logtofile set logtofile=true
if defined deldefargsfile if exist "%defargsfile%" ECHO del /q "%defargsfile%"


REM Show given switches (just as example)
echo Given switches:
for /F "tokens=1* delims==" %%a in ('set switch[') do (
   if defined %%b (
      echo - %%b
      if "!%%b!" neq "true" echo      -^> "!%%b!"
   )
)
goto :EOF

:usage
echo Invalid switch: %badSwitch%

Output examples:

Code: Select all

C:\> test /O /V /C
Given switches:
- createlogdir
- overwrite
- logtoscrn

C:\> test /O /V /C /T:pathWithNoSpaces
Given switches:
- createlogdir
- overwrite
- toolsdir
     -> "pathWithNoSpaces"
- logtoscrn

C:\> test /O /V /C /T:"path With Spaces"
Given switches:
- createlogdir
- overwrite
- toolsdir
     -> "path With Spaces"
- logtoscrn

Antonio

ldoodle
Posts: 18
Joined: 26 Sep 2015 04:01

Re: IF: [ ] vs " "

#10 Post by ldoodle » 02 Oct 2015 06:16

Like an absolute boss!

Thanks :)

Post Reply