cmd.exe:复杂的条件?

时间:2010-05-05 10:04:45

标签: windows batch-file conditional

在DOS批处理文件中,在IF语句中,是否可以使用AND或OR组合两个或多个条件?我无法找到任何文件

修改 - help if并且MS文档没有说明在if中使用多个条件。

我想AND的解决方法是做

if COND1 (
  if COND2 (
    cmd
  )
)

但这正是我想要避免的。

6 个答案:

答案 0 :(得分:14)

不,没有更简单的方法。

对于and,您也可以在不引入块的情况下链接它们:

if COND1 if COND2 ...

坦率地说,并不比

更糟糕
if COND1 and COND2 ...

然而,对于or来说,确实更加丑陋:

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

或:

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

我曾经看过一个批处理预处理器,它使用类似C的语法来控制流和中间的批处理,然后将这些条件转换成多个跳转和检查。但是,那个东西是针对DOS批处理文件的,在Windows环境中几乎没有用。

答案 1 :(得分:9)

我有时想知道,现在人们在学校里学到了什么!当然'OR'也是可能的。任何可以为您提供“NOT”和“AND”的系统都会自动为您提供“OR”,因为:

x OR y = NOT((不是x)和(不是y))请参阅http://en.wikipedia.org/wiki/De_Morgan%27s_laws

只要表达式“if(x AND y)then do z”就可以这样写出:

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

...我们应该能够写出表达式“if(x OR y)then do z”,但是存在问题:

我们在哪里放第一个'NOT'?嗯,答案是无处可去的,我们应该先将上面的等式改为:

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

根据这个,我们可以写“if(NOT(x OR y))then(do z)”as:

“if((NOT x)AND(NOT y))then(do z)”

有了这个并且知道如何表达AND如上所示,我们现在可以将表达式“if(NOT(x OR y))然后(do z)”写为:

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

我们也知道表达式:

“if(NOT p)then(do q)else(do r)”

......相当于:

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

因此我们可以写“if(x OR y)then(do z)”:

“if(NOT(x OR y))然后(什么都不做)else(do z)”

所以我们可以表达“if(x OR y)then(do z)” as:

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

但这还没有完成,因为这不是一个真正的'AND'而是一个“模拟”的。缺少的是第二个。因此,获得正确结果的完整形式应该是:

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

......其中有丑陋的另外一部分。你可以用'goto'来解决这个问题,我们终于有:

rem if (x OR y) then (do z):
if (not x) ( if (not y) (goto :doNothing) )
rem do z
:doNothing

答案 2 :(得分:2)

对于AND解决方法我同意Joey,我看不到另一种解决方案。

对于OR解决方法,我会建议以下'技巧':
假设您要在测试批处理文件时测试用户是否在命令行上寻求帮助,例如:thebatch /?
但是你不知道用户是否会输入/?或者更确切地说(是一个Unix习惯用户)--help-h,或者甚至忘记传递任何参数。

您的代码可以是:

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

但请注意,测试“/?”要么 ”-?”字符串不适用于该技巧(FOR循环不喜欢?元字符。) 为此,只需在块顶部添加行if "%1"=="/?" goto help(请参阅 ':help' 循环中的for标签 ?)

另请注意,在TCC.EXE(Take Command解释器,完全版或精简版)下使用批处理文件时,此语法不起作用(只是完全被忽略,代码无法执行)但在这种情况下只是将他们的语法与.OR..AND.关键字一起使用。

希望这有帮助。

答案 3 :(得分:0)

如果您的条件是检查变量的特定值,您可以将其设置为CASE语句。我需要检查TYPE是单个成员还是(或全部)组。

注意:标签不区分大小写。

如果任何条件为真(如果TYPE==ALLTYPE==GROUP1TYPE==GROUP2,则执行代码块,否则执行会跳过块

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

我不喜欢Mehrdad的电气工程(数字电子)方法。虽然准确,但在软件工程方面,OP所指出的想法是让事情变得更简单。嵌套if语句添加Complexity (McCabe)。添加额外的NOT并没有帮助。

如果您不知道goto-label / error设置,我的解决方案有点奇怪,但它的结构扁平,大致设置为if-statement,带有多个OR&#39 ; d条件不难解读。

答案 4 :(得分:0)

IF <COND1> IF <COND2> ACTION

OR:

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

为了以这种方式实现OR,您需要扩展命令。

答案 5 :(得分:-6)

只要启用了命令扩展,就可以使用比较运算符。

这是直接粘贴在“help if”:

如果启用了命令扩展,则IF更改如下:

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

其中compare-op可能是以下之一:

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

和/ I切换,如果指定,则表示不区分大小写的字符串 相比较。 / I开关也可以在string1 == string2表单上使用 IF。这些比较是通用的,因为如果string1和 string2都包含所有数字,然后是字符串 转换为数字并执行数字比较。