cmd.exe:复杂的条件?

在DOSbatch file中,在IF语句中,是否可以使用AND或OR来组合两个或更多个条件? 我无法find任何文件

编辑help if MS文档没有说在if中使用多个条件。

我想一个解决方法是要做

 if COND1 ( if COND2 ( cmd ) ) 

但这正是我想要避免的。

不,没有简单的方法。

因为你也可以链接它们而不用引入块:

 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环境中几乎没有用处。

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

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

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

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

…我们应该可以写下“if(x OR y)then z”这个表达式, 但是还有一个问题:

我们在哪里放第一个“不”? 那么答案是没有的,我们应该先把上面的方程式改成:

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

据此,我们可以把“if(NOT(x OR y))then(do z)”写为:

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

有了这个,知道如何表达AND,如上所示,我们现在可以将表达式“if(NOT(x OR y))then(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))then(do nothing)else(do z)”

所以我们可以把“if(x OR y)then(do z)”表示为:

 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 

对于我和乔伊同意的AND解决方法,我看不到另一个解决方案。

对于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循环不喜欢? meta字符)。
为此,只需添加以下行: if "%1"=="/?" goto help if "%1"=="/?" goto help块的顶部if "%1"=="/?" goto help (请参阅for 循环 内的 ':help'标签?)

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

希望这可以帮助。

如果您的条件正在检查某个变量的特定值,则可以将其设置为CASE语句。 我有一个需要检查是否类型是个人成员或组(或全部)

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

如果任何条件为真(如果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语句添加复杂性(McCabe) 。 添加额外的NOT不会帮助。

如果你不知道goto-label / error的设置,我的解决方案有点奇怪,但是它是一个扁平的结构,它被粗略地设置成一个if语句,其中有几个OR'd条件是不难以破译的。

和:

 IF <COND1> IF <COND2> ACTION 

要么:

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

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

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

这是直接粘贴从“帮助如果”:

如果启用命令扩展如果更改如下:

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

比较操作可以是以下之一:

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

和/ I开关,如果指定,说做不区分大小写的字符串比较。 / I开关也可以用于IF的string1 == string2形式。 这些比较是通用的,因为如果string1和string2都是由所有数字组成,那么这些字符串被转换为数字,并进行数字比较。