在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==ALL
或TYPE==GROUP1
或TYPE==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都是由所有数字组成,那么这些字符串被转换为数字,并进行数字比较。