Page 1 of 2

IF Statement Syntax

Posted: 01 Aug 2011 12:19
by Acy Forsythe
I could have sworn that this syntax worked, but maybe I'm losing my mind...

Code: Select all

    IF "!Check!"=="BH" || IF "!Check!"=="TD" || IF "!Check!"=="RB" || IF "!Check!"=="RC" || IF "!Check!"=="AB" (
    Some Commands
   ) ELSE (
   Other Commands
   )


It's telling me that | was unexpected at this time...

Re: IF Statement Syntax

Posted: 01 Aug 2011 13:09
by dbenham
Nope ( I hope someone returns your mind :lol: )

You might have gotten confused with something that looks similar:

Code: Select all

SomeCommand && (
  Do Some commands if SomeCommand was successful (ERRORLEVEL=0)
) || (
  Else do some other commands if SomeCommand failed (ERRORLEVEL<>0)
)
Of course you could use && without ||, or vice versa.

For a generic simulation of an IF x OR y you could do something like this pseudo code:

Code: Select all

set "test="
if <CONDITION 1> set test=1
if <CONDITION 2> set test=1
...
if <CONDITION N> set test=1
if defined test (
  <Some Commands>
) else (
  <Other Commands>
)

If you can get away with a case insensitve comparison, then your specific example could be coded as:

Code: Select all

set "test=/BH/TD/RB/RC/AB/"
if "!test:/%Check%/=!" neq "!test!" (
  <Some Commands if found a match>
) else (
  <Other Commands>
)

If you need case sensitive, then this would work as long as all options have differences other than just case:

Code: Select all

set "test=/BH/TD/RB/RC/AB/"
if "!test:/%Check%/=!" neq "!test!" if "!test:/%Check%/=/%Check%/!" equ "!check!" (
  <Some Commands if found a match>
) else (
  <Other Commands>
)


Dave Benham

Re: IF Statement Syntax

Posted: 01 Aug 2011 13:18
by Acy Forsythe
Where did you find this syntax?

Code: Select all

set "test=/BH/TD/RB/RC/AB/"
if "!test:/%Check%/=!" neq "!test!" (
  <Some Commands if found a match>
) else (
  <Other Commands>
)

Re: IF Statement Syntax

Posted: 01 Aug 2011 13:45
by dbenham
I wouldn't call it syntax. It's a technique I've used here and there that uses standard syntax.

Simply build a delimited string of all options. Then search the string for your variable and replace with nothing. If the replaced string doesn't match the original, then you know you have a case insensitive match with one of the options.

Dave Benham

Re: IF Statement Syntax

Posted: 01 Aug 2011 14:38
by Acy Forsythe
That's awsome! Thanks Dave.

I guess I assumed :( at some point that since DOS would parse && and || that it would parse them anywhere, much like many of the other little tricks that work in multiple places.

Re: IF Statement Syntax

Posted: 01 Aug 2011 15:05
by dbenham
You can use && and || after any VALID command.

But an IF statement is not valid unless it has a valid command following the condition.

Dave Benham

Re: IF Statement Syntax

Posted: 02 Aug 2011 15:51
by Acy Forsythe
Dang :(

This is great, but it doesn't work if you also have to expand !Check!...

Code: Select all

set "test=/BH/TD/RB/RC/AB/"
if "!test:/!Check!/=!" neq "!test!" (
  <Some Commands if found a match>
) else (
  <Other Commands>
)


!Check! doesn't expand and so nothing gets replaced with nothing. I think I see potential here for one of those Call Call Set tricks, but if you know of another way or know that that won't work, feel free to stop me from bleeding on my keyboard :)

Otherwise, it looks like I might duplicate a LOT of code here...

Re: IF Statement Syntax

Posted: 02 Aug 2011 16:16
by dbenham
One of the reasons for this post is for issues like you are having now. It is not uncommon to have to do different levels of expansion within the same statement. The post shows all the levels that can be employed. There is usually a reasonable solution to most problems, it just may not be as direct as you hoped.

In your case, you can solve the problem by placing the value of !Check! in a FOR variable:

Code: Select all

set "test=/BH/TD/RB/RC/AB/"
for /f "delims=" %%a in ("/!Check!/") do (
  if "!test:%%a=!" neq "!test!" (
    <Some Commands if found a match>
  ) else (
    <Other Commands>
  )
)

By including the / delimiters in the FOR variable, we don't have to worry about the possibility of !Check! beginning with a semicolon - The implicit FOR /F "EOL=;" option won't do any harm.


You could use the CALL trick, but it would be MUCH slower then the above.

Dave Benham

Re: IF Statement Syntax

Posted: 02 Aug 2011 17:26
by Acy Forsythe
Thanks again Dave! I'll have to play around with that tomorrow... I was thinking about the test string you created, it won't change and can be set outside of a command block. I'm going to fool around with that tomorrow and see if I can get this to work instead:

Code: Select all

if "%test:/!Check!/=%" neq "%test%"


But your last post only added one line of code and changed my IF test.

Code: Select all

FOR /f "delims=" %%a IN ("/!Check!/") DO (IF "!test:%%a=!" neq "!test!" (SET "STN=G"))
...
IF "!STN!"=="G" (
     Do my found a match commands
) ELSE (
     Do my no match found commands
)

Re: IF Statement Syntax

Posted: 02 Aug 2011 17:41
by dbenham
Acy Forsythe wrote:Thanks again Dave! I'll have to play around with that tomorrow... I was thinking about the test string you created, it won't change and can be set outside of a command block. I'm going to fool around with that tomorrow and see if I can get this to work instead:

Code: Select all

if "%test:/!Check!/=%" neq "%test%"


Think about the order in which the various types of expansion occur. You will realize that the above can't possibly work :!: :wink:

immediate expansion 1st (%var%)
FOR variable expansion 2nd (%%v)
delayed expansion 3rd (!var!)
Finally set /a variable expansion last

Dave Benham

Re: IF Statement Syntax

Posted: 03 Aug 2011 07:54
by Acy Forsythe
Ahah! (Maybe)...


Check is actually set as the first 2 characters of %%~C in a FOR loop... But only the first 2 characters. Right after my Ahah! moment though I realized that I had already tried to do something like:

SET Check=%%C:~1,2%

And was told I had to put it in two set statements to do it... (In another thread).

I was reading your other post on the expansion levels and I "Think" just maybe I could get this to work, but I also think it's over my head at the moment.

I also just realized that in my ~300 line batch file, while the logic and flow is mostly mine, the syntax is mostly yours, Ed's and Jebs with a little aGerman thrown in. You guys deserve some credit this script is superb. And... Almost done :) And not a single :function call.

Re: IF Statement Syntax

Posted: 03 Aug 2011 08:51
by Ed Dyreen
'
And was told I had to put it in two set statements to do it... (In another thread).
Because ':~1,2' works only for variables which have to be defined beforehand, which makes two statements.

Code: Select all

set "$var=This works" &for %%! in ( "$var" ) do set "%%~!=!%%~!:~1,2!"
Interesting expansion experiment:
viewtopic.php?f=3&t=2097&start=0
And not a single :function call.
I'm impressed, we'll talk again when you hit the 8k barrier. :wink:

Re: IF Statement Syntax

Posted: 03 Aug 2011 09:31
by dbenham
Ed Dyreen wrote:'

Code: Select all

set "$var=This works" &for %%! in ( "$var" ) do set "%%~!=!%%~!:~1,2!"

Or better yet, a more direct and less obfuscated way based on Acy's original code:

Code: Select all

set "Check=%%C"
set "Check=!Check~1,2!"

Or perhaps even better, do the substring within the FOR loop IN () clause:

Code: Select all

FOR /f "delims=" %%a IN ("/!Check~1,2!/") DO (IF "!test:%%a=!" neq "!test!" (SET "STN=G"))

So many choices. :wink:

Dave Benham

Re: IF Statement Syntax

Posted: 03 Aug 2011 09:46
by Acy Forsythe
Well, since I was already having to use a FOR loop to check (which is ok, it's fast enough) I went with:

Code: Select all

   SET Check=%%C
   SET "test=/BH/TD/RB/RC/AB/" <--- Just moved this outside of the loop.
   FOR /f "delims=" %%a IN ("/!Check~1,2!/") DO (IF "!test:%%a=!" neq "!test!" (SET "STN=G"))


The script runs through in a total of 16 minutes and it's done... On my Win7 Dev machine. On my XP test laptop which is 4 years older, total run-time is 37 minutes :(

Re: IF Statement Syntax

Posted: 03 Aug 2011 18:33
by Ed Dyreen
'
Speed is a real problem in DOS scripts, you already are using macros and you are probably also avoiding the call command.
I see no room for further speed enhancements in DOS :(

You could speed things up if you rewrite it as VBScript.
You could speed it up even further if you used a real programming language that can be compiled.
I personally would go for AutoIT, but it doesn't qualify as a real programming language.
Many people unfamiliar with AutoIT believe it is difficult to learn, this is completely false !
It's much easier than DOS coding.