cmd.exe: complex conditions?

后端 未结 6 788
没有蜡笔的小新
没有蜡笔的小新 2021-01-08 01:25

in DOS batch files, In an IF statement, is it possible to combine two or more conditions using AND or OR ? I was not able to find any documentation for that

相关标签:
6条回答
  • 2021-01-08 01:42

    As long as command extensions are enabled, you can use compare-operators.

    This is directly pasted from "help if":

    If Command Extensions are enabled IF changes as follows:

    IF [/I] string1 compare-op string2 command
    IF CMDEXTVERSION number command
    IF DEFINED variable command
    

    where compare-op may be one of:

    EQU - equal
    NEQ - not equal
    LSS - less than
    LEQ - less than or equal
    GTR - greater than
    GEQ - greater than or equal
    

    and the /I switch, if specified, says to do case insensitive string compares. The /I switch can also be used on the string1==string2 form of IF. These comparisons are generic, in that if both string1 and string2 are both comprised of all numeric digits, then the strings are converted to numbers and a numeric comparison is performed.

    0 讨论(0)
  • 2021-01-08 01:51

    AND:

    IF <COND1> IF <COND2> ACTION
    

    OR:

    (SET _=) & (IF <COND1> (SET _= ) ELSE IF <COND2> (SET _= )) & IF DEFINED _ ACTION
    

    For implementing OR this way, you do need command extensions.

    0 讨论(0)
  • 2021-01-08 01:55

    I sometimes wonder, what people learn at school nowadays! Of course 'OR' is possible too. Any system that can provide you with a 'NOT' and an 'AND', automatically provides you with an 'OR' too, because:

    x OR y = NOT ( (NOT x) AND (NOT y) ) see http://en.wikipedia.org/wiki/De_Morgan%27s_laws

    So as long as the expression "if (x AND y) then do z" can be written like this:

    if (x) if (y) (do z)
    

    ... we should be able to write the expression "if (x OR y) then do z", but there is a problem:

    Where shall we put the first 'NOT'? Well, the answer is nowhere, we should reform the equation above first to:

    NOT ( x OR y ) = (NOT x) AND (NOT y)

    According to this, we may write "if (NOT(x OR y)) then (do z)" as:

    "if ((NOT x) AND (NOT y)) then (do z)"

    Having this and knowing how to express AND as shown above, we can now write the expression "if (NOT(x OR y)) then (do z)" as:

    if (not x) if (not y) (REM do z)
    

    We also know that the expression:

    "if (NOT p) then (do q) else (do r)"

    ... is equivalent to:

    "if (p) then (do r) else (do q)

    Thus we can write for "if (x OR y) then (do z)":

    "if (NOT(x OR y)) then (do nothing) else (do z)"

    So we can express "if (x OR y) then (do z)" as:

    if (not x) if (not y) (REM do nothing) else (REM do z)
    

    But this is not complete yet, because this is not a true 'AND' but a "simulated" one. What is missing is the second else. So the complete form to get the correct result should be:

    if (not x) ( if (not y) (REM do nothing) else (REM do z) ) else (REM do z) )
    

    ... which has the ugly double else part. You can solve that with a 'goto' and we finally have:

    rem if (x OR y) then (do z):
    if (not x) ( if (not y) (goto :doNothing) )
    rem do z
    :doNothing
    
    0 讨论(0)
  • 2021-01-08 01:57

    No, there is no easier way.

    For and you can also just chain them without introducing blocks:

    if COND1 if COND2 ...
    

    which frankly isn't any worse than

    if COND1 and COND2 ...
    

    However, for or it gets uglier, indeed:

    set COND=
    if COND1 set COND=1
    if COND2 set COND=1
    if defined COND ...
    

    or:

    if COND1 goto :meh
    if COND2 goto :meh
    goto :meh2
    :meh
    ...
    :meh2
    

    I once saw a batch preprocessor which used C-like syntax for control flow and batch stuff in between and then converted such conditionals into multiple jumps and checks. However, that thing was for DOS batch files and was of little to no use in a Windows environment.

    0 讨论(0)
  • 2021-01-08 01:59

    For the AND workaround I agree with Joey, I cannot see another solution.

    For the OR workaround I would propose the following 'trick':
    Lets say that you want to test if user asked for help on the command line while calling for your batch file, something like: thebatch /?.
    But you don't know if the user will type /? or rather (being a Unix accustomed user) --help or -h or even forget to pass any argument at all.

    Your code could be like:

    for %%P in ("" "-h" "--help") do if "%1"==%%P (
       :help
       echo this is my help...  >&2
       exit /b 9
    )
    

    Note however that testing "/?" or "-?" strings won't work with that trick (FOR loops don't like the ? meta character).
    For that purpose, just add the line: if "%1"=="/?" goto help on top of the block (see the ':help' label inside the for loop ?)

    Note too that this syntax won't work (it is just completely ignored and code won't be executed) with batch files under TCC.EXE (the Take Command interpreter, either full or lite edition) but in that case just use their syntax with their .OR. and .AND. keywords.

    Hope this helps.

    0 讨论(0)
  • 2021-01-08 02:04

    If your conditions are checking for specific values of a variable, you might be able to set it up like a CASE statement. I had a need to check if the TYPE was an individual member or a group (or all).

    Note: labels are case insensitive.

    If any of the conditions are true (if TYPE==ALL or TYPE==GROUP1 or TYPE==GROUP2), then the code block executes, otherwise execution skips over the block.

    goto :TYPE_EQ_%TYPE% 2>NUL
    if %ERRORLEVEL% neq 0 goto :END_CASE_TYPE
    :TYPE_EQ_ALL
    :TYPE_EQ_GROUP1
    :TYPE_EQ_GROUP2
    rem do what you need
       echo GROUP: %TYPE%
    :END_CASE_TYPE
    

    I don't like Mehrdad's Electrical Engineering (digital electronics) approach. While accurate, with software engineering, the idea, as indicated by the OP, is to make things simpler to figure out. Nested if statements add Complexity (McCabe). Adding extra NOTs doesn't help.

    My solution is a little odd if you don't know the goto-label/error set-up, but it's a flat structure that is roughly set up like an if-statement with several OR'd conditions that are not to hard to decipher.

    0 讨论(0)
提交回复
热议问题