关于cmd:DOS批处理中的逻辑运算符(“和”,“或”)

Logical operators (“and”, “or”) in DOS batch

您将如何在DOS Batch文件中实现逻辑运算符?


您可以对嵌套条件执行AND

1
2
3
4
5
if %age% geq 2 (
    if %age% leq 12 (
        set class=child
    )
)

要么:

1
if %age% geq 2 if %age% leq 12 set class=child

您可以使用单独的变量执行OR

1
2
3
4
5
6
set res=F
if %hour% leq 6 set res=T
if %hour% geq 22 set res=T
if"%res%"=="T" (
    set state=asleep
)


IF语句不支持逻辑运算符(ANDOR),级联的IF语句进行隐式连接。

1
IF Exist File1.Dat IF Exist File2.Dat GOTO FILE12_EXIST_LABEL

如果File1.DatFile1.Dat存在,则跳转标签FILE12_EXIST_LABEL

另请参阅:IF /?


德摩根定律允许我们仅使用连词("与")和否定("非")将析取词(" OR")转换为逻辑等价物。这意味着我们可以将析取词(" OR")链接到一条线上。

这意味着如果名称是" Yakko"或" Wakko"或" Dot",则回显" Warner兄弟姐妹"。

1
2
3
set warner=true
if not"%name%"=="Yakko" if not"%name%"=="Wakko" if not"%name%"=="Dot" set warner=false
if"%warner%"=="true" echo Warner brother or sister

这是paxdiablo的" OR"示例的另一个版本,但条件链接到一行。 (请注意,leq的对面是gtrgeq的对面是lss。)

1
2
3
set res=true
if %hour% gtr 6 if %hour% lss 22 set res=false
if"%res%"=="true" set state=asleep

以下示例说明如何制作AND语句(用于设置变量或包括命令的参数)。

要启动记事本并关闭CMD窗口,请执行以下操作:

1
start notepad.exe & exit

如果变量" a"等于等等,则将变量x,y和z设置为值。

1
IF"%a%"=="blah" (set x=1) & (set y=2) & (set z=3)

希望有帮助!


OR有点棘手,但并非如此。这是一个例子

1
2
3
4
5
6
7
set var1=%~1
set var2=%~2
::
set or_=
if"%var1%"=="Stack" set or_=true
if"%var2%"=="Overflow" set or_=true
if defined or_ echo Stack OR Overflow

如果您有兴趣在一个语句中写一个if + AND / OR,则没有任何内容。 但是,您仍然可以将if&& / ||( / )语句分组,以在一行中实现所需的任何变量,并且不包含if-else块重复( TRUEFALSE代码段的单个echo命令):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@echo off

setlocal

set"A=1" & set"B=2" & call :IF_AND
set"A=1" & set"B=3" & call :IF_AND
set"A=2" & set"B=2" & call :IF_AND
set"A=2" & set"B=3" & call :IF_AND

echo.

set"A=1" & set"B=2" & call :IF_OR
set"A=1" & set"B=3" & call :IF_OR
set"A=2" & set"B=2" & call :IF_OR
set"A=2" & set"B=3" & call :IF_OR

exit /b 0

:IF_OR
( ( if %A% EQU 1 ( type nul>nul ) else type 2>nul ) || ( if %B% EQU 2 ( type nul>nul ) else type 2>nul ) || ( echo.FALSE-& type 2>nul ) ) && echo TRUE+

exit /b 0

:IF_AND
( ( if %A% EQU 1 ( type nul>nul ) else type 2>nul ) && ( if %B% EQU 2 ( type nul>nul ) else type 2>nul ) && echo.TRUE+ ) || echo.FALSE-


exit /b 0

输出:

1
2
3
4
5
6
7
8
9
TRUE+
FALSE-
FALSE-
FALSE-

TRUE+
TRUE+
TRUE+
FALSE-

诀窍在type命令中,该命令放下/设置errorlevel,从而处理通向下一个命令的方式。


就像下面这样简单:

AND>如果+如果

1
if"%VAR1%"=="VALUE" if"%VAR2%"=="VALUE" *do something*

OR>如果//如果

1
2
3
4
set BOTH=0
if"%VAR1%"=="VALUE" if"%VAR2%"=="VALUE" set BOTH=1
if"%BOTH%"=="0" if"%VAR1%"=="VALUE" *do something*
if"%BOTH%"=="0" if"%VAR2%"=="VALUE" *do something*

我知道还有其他答案,但我认为我的问题更简单,因此更容易理解。希望这对您有所帮助! ;)


Athul Prakash(当时16岁)通过否定IF语句中的条件,然后使用ELSE子句作为放置需要执行代码的位置,给出了如何实施OR测试的逻辑思路。我自以为是,由于他建议使用两个IF语句,因此通常需要另外两个子句,因此执行的代码需要编写两次。但是,如果使用GOTO跳过了所需的代码,则无需编写ELSE子句,只需编写一次即可执行代码。

这是一个可测试的示例,说明了我将如何实现Athul Prakash的否定逻辑来创建OR。

在我的示例中,如果有人拥有坦克许可证或正在服兵役,则允许其驾驶坦克。在两个提示下输入true或false,您将能够查看该逻辑是否允许您驾驶坦克。

1
2
3
4
5
6
7
8
9
10
11
@ECHO OFF
@SET /p tanklicence=tanklicence:
@SET /p militaryservice=militaryservice:

IF /I NOT %tanklicence%==true IF /I NOT %militaryservice%==true GOTO done

ECHO I am driving a tank with tanklicence set to %tanklicence% and militaryservice set to %militaryservice%

:done

PAUSE

尝试取反操作数-'不'!

好吧,如果您可以使用嵌套的" if"对if语句执行" AND"运算(请参阅前面的答案),那么可以对" if not"执行相同的操作来执行" or"运算。

如果您还没有这个主意,请继续阅读。否则,请不要浪费时间回到编程上。

就像只有在所有条件都成立时才满足嵌套的"如果",也只有在所有条件都为假时才满足嵌套的"如果不是"。这类似于您要对"或"操作数执行的操作,不是吗?

即使嵌套的"如果不是"中的任何一个条件为真,整个语句仍然不满足。因此,您可以通过记住条件语句的主体应该是您想在所有嵌套条件均为假的情况下执行的操作来连续使用否定的" if"。您实际想要给出??的主体应位于else语句下。

而且,如果您仍然不明白这件事,对不起,我16岁,这是我能尽力解释的最好的事情。


另一种选择是寻找一个unix shell,它确实为您提供逻辑运算符以及更多其他功能。如果不想走cygwin路线,可以在这里获得Bourne shell的本地win32实现。本地bash可以在这里找到。我敢肯定,您可以轻松地用Google搜索其他好的替代方法,例如zsh或tcsh。

?


稍微修改了Andry的答案,减少了重复类型的命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
set"A=1" & set"B=2" & call :IF_AND
set"A=1" & set"B=3" & call :IF_AND
set"A=2" & set"B=2" & call :IF_AND
set"A=2" & set"B=3" & call :IF_AND

echo.

set"A=1" & set"B=2" & call :IF_OR
set"A=1" & set"B=3" & call :IF_OR
set"A=2" & set"B=2" & call :IF_OR
set"A=2" & set"B=3" & call :IF_OR

goto :eof

:IF_OR

(if /i not %A% EQU 1 (
   if /i not %B% EQU 2 (
      echo FALSE-
      type 2>nul
   )
)) && echo TRUE+

goto :eof

:IF_AND


(if /i %A% EQU 1 (
   if /i %B% EQU 2 (
      echo TRUE+
      type 2>nul
   )
)) && echo FALSE-

goto :eof