繁体   English   中英

cmd.exe:复杂的条件?

[英]cmd.exe: complex conditions?

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

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

我想AND的解决方法就是做

if COND1 (
  if COND2 (
    cmd
  )
)

但这正是我想要避免的。

不,没有更简单的方法。

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

我有时想知道,现在人们在学校里学到了什么! 当然'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(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)”

有了这个并且知道如何表达和如上所示,我们现在可以将表达式“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))then(什么都不做)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解决方法我同意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循环不喜欢? meta字符)。
为此,只需添加以下行: if "%1"=="/?" goto help if "%1"=="/?" goto help在块的顶部(见':help' 里面的标签for环路

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

希望这可以帮助。

如果您的条件是检查变量的特定值,则可以将其设置为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设置,我的解决方案有点奇怪,但它是一个扁平结构,大致设置为具有几个OR'd条件的if语句,这些条件不难解读。

和:

IF <COND1> IF <COND2> ACTION

要么:

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

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

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

这是直接粘贴“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开关也可以用于IF的string1 == string2形式。 这些比较是通用的,因为如果string1和string2都包含所有数字,则字符串将转换为数字并执行数字比较。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM