在DOS批处理文件中,在IF
语句中,是否可以使用AND或OR组合两个或多个条件?我无法找到任何文件
修改 - help if
并且MS文档没有说明在if中使用多个条件。
我想AND的解决方法是做
if COND1 (
if COND2 (
cmd
)
)
但这正是我想要避免的。
答案 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==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语句添加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都包含所有数字,然后是字符串 转换为数字并执行数字比较。