10

What is the simplest and/or most readable method to IF with AND in a CMD shell? In pseudo code:

IF EXIST file1 AND file2:
   then do stuff
ELSE: 
   do something else

this Q has to be somewhere on SO but my search-fu isn't working for this one. sorry

matt wilkie
  • 17,268
  • 24
  • 80
  • 115
  • 1
    if testing files, you may also want to look here: http://stackoverflow.com/questions/12348446/searching-for-multiple-files-in-a-directory-and-provide-feedback/12349487#12349487 – wmz Jan 31 '13 at 09:49

5 Answers5

16

Assuming you are talking about DOS/Windows batch files, I think you want something like this:

SET do_stuff=false
IF EXIST file1 IF EXIST file2 SET do_stuff=true
IF "%do_stuff%"=="true" (
    REM do stuff
) ELSE (
    REM do something else
)

The source of the ugliness is that DOS batch file if statements do not have and and or operators, so you have to either write nested if statements (which can lead to duplicated code in the then and else clauses), or capture the expression result into a variable and then do an if statement on its value (lots more lines). I favor the second approach to avoid duplication of code. Perhaps this is all a security feature. :)

I found some good examples here and here (SO, even). But you can also just use the help system built into the shell (help if or if /? IIRC).

Community
  • 1
  • 1
Randall Cook
  • 6,728
  • 6
  • 33
  • 68
  • Verbose but much better than the nested and confusing IF..THEN..IF..THEN..ELSE things I had created before I got fed up and asked for help! and that SO thread looks very much like what I thought I should have been able to find but couldn't. Thanks. – matt wilkie Jan 30 '13 at 21:22
  • Accepted as correct answer for the critical piece of `if exist ... if exist` having same effect as AND, though I'm using GOTO/CALL now instead of SET in response to the test (see other answers). – matt wilkie Feb 29 '16 at 22:16
6

An alternative to the rather nice suggestion by @Randall Cook could be going like this:

IF EXIST file1 IF EXIST file2 (
  do stuff
  GOTO cont
)
do something else

:cont
get on with other stuff
Community
  • 1
  • 1
Andriy M
  • 76,112
  • 17
  • 94
  • 154
  • I like how you use the `GOTO` to simulate an `ELSE` clause that works for both cases of file nonexistence. After all, a compiler would generate similar code. +1. Somehow I got the idea that gotos should be avoided, and I don't usually consider them when coding. Perhaps that's wrong. – Randall Cook Jan 31 '13 at 18:30
  • Thanks! I guess I'm actually with you in regard to the usage of GOTOs in general, i.e. I prefer to avoid them too. I have never had really strong feelings against them, though, like considering them *evil* or something. And even less so in batch scripting, where you can find many basic features missing and a GOTO can actually help you to implement some of them. (For instance, in the absence of a "while" loop, I'd probably go with IF + GOTO.) Or, if nothing else, it may sometimes make your script simpler looking, even if not really simpler. :) – Andriy M Jan 31 '13 at 19:49
6
IF EXIST A (
    IF EXIST B (
        ECHO A and B exist
        )
    )
matt wilkie
  • 17,268
  • 24
  • 80
  • 115
Shirulkar
  • 484
  • 2
  • 4
  • Great and elegant answer! In this way you don't need to use an extra variable nor `GOTO`. – itsho Aug 06 '19 at 08:21
  • @itsho: It's an elegant solution for when you don't have an "else" part. The OP does have an "else" though, and this answer offers no implementation for it. – Andriy M Jan 24 '20 at 07:39
1

I've learned a bit since @RandallCook's answer was the best for me. This is what I'd use now:

@echo off
IF EXIST "File1" IF EXIST "File2" GOTO :do_stuff
GOTO :not_exist
GOTO :EOF

:do_stuff
    echo File1 and File2 exist.
    echo -- Doing stuff here...
    goto :EOF

:not_exist
    echo  Condition not met, not doing stuff.
    goto :EOF

:EOF a predefined label that will exit the current subroutine or script.

For those that prefer CALL over GOTO because it leads to cleaner code in longer scripts, we need to complicate things a little bit, but is still readable:

@echo off
:: Successful CD resets errorlevel to 0, in case it was already set this shell
cd
IF EXIST "File1" IF EXIST "File2" CALL :do_stuff
IF ERRORLEVEL 10 GOTO :EOF
CALL :not_exist
GOTO :EOF

:do_stuff
    echo File1 and File2 exist.
    echo -- Doing stuff here...
    exit /b 10
    goto :EOF

:not_exist
    echo  Condition not met, not doing stuff.
    goto :EOF
Community
  • 1
  • 1
matt wilkie
  • 17,268
  • 24
  • 80
  • 115
0
set /p k="Please enter Choice : "

if "%k%" == "A" goto A if "%k%" == "B" goto B

:A echo "Hello from A" :B echo "Hello from B"

Sheshan Gamage
  • 574
  • 11
  • 19
  • thanks for the contribution, but it wouldn't work in this case. The scenario is automatic, with no user intervention. – matt wilkie Feb 29 '16 at 21:30