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


Answers:


289

您可以and使用嵌套条件:

if %age% geq 2 (
    if %age% leq 12 (
        set class=child
    )
)

要么:

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

您可以or使用一个单独的变量:

set res=F
if %hour% leq 6 set res=T
if %hour% geq 22 set res=T
if "%res%"=="T" (
    set state=asleep
)

14
您也可以只使用set res=or set res=1,然后再使用if defined res它来抵御拼写错误,甚至可以在没有显式启用延迟扩展的情况下在块中使用。
乔伊(Joey)2010年

5
只是为了稍微提高您的答案...您不需要显式嵌套“ if”语句...您可以“将其”“链接”,如Dave Jarvis在下面演示的那样
JoelFan 2010年

请确保在set = true之后不要留任何空格,否则恰好不能正常工作。它将在变量中存储值“ true” ...
Roland Pihlakas 2015年

1
您描述的“或”条件很平滑,并且适用于一定范围的数字,但是如果我要比较两个独立的值而不是范围,该怎么办?例如,如果此文件存在或文件名==“”
bakoyaro

1
@bakoyaro,您可以使用任何条件将res设置为true,包括您提到的条件。
paxdiablo

69

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

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

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

也可以看看: IF /?


53

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

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

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”示例的另一个版本,但条件链接到一行。(请注意,leqis gtr的反义词与geqis 的反义词lss。)

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

6

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

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

start notepad.exe & exit

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

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

希望有帮助!


5

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

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

2

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

这是一个如何测试Athul Prakash的否定逻辑以创建OR的可测试示例。

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

@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

2

如果您有兴趣在一个语句中编写if+ AND/ OR,那么就没有任何内容。但是,您仍然可以if&&/ ||(/ )语句组合在一起,以在一行中不包含任何其他变量和不包含if-else块重复的情况echo下实现所需的代码(用于TRUEFALSE代码段的单个命令):

@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

输出

TRUE+
FALSE-
FALSE-
FALSE-

TRUE+
TRUE+
TRUE+
FALSE-

诀窍在type命令中,它放下/设置了errorlevel,因此可以处理下一条命令。


1

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

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

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

就像只有在所有条件都为真时才满足嵌套的“ if”一样,只有在所有条件都为false时才满足嵌套的“ if”。这类似于您要对“或”操作数执行的操作,不是吗?

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

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


x = 2或x = 3 =>!!(x = 2或x = 3)=>!(x!= 2和x!= 3)我认为,如果要应用必要的外部“ not”运算符的结构,您不能否定整体。已经3年了,@ Athul-prakash,有什么想法吗?
Azeroth2b

1

就像下面这样简单:

AND>如果+如果

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

OR>如果//如果

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*

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


0

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

ķ


4
如果您要尝试使用其他Shell,请至少使用PowerShell:microsoft.com/powershell
Eclipse 2010年

17
有许多比DOS更好的外壳。我之所以使用DOS蝙蝠文件,是因为它不需要任何外部工具。如果您的客户需要自动化一些简单的操作,您是否真的希望他们在BAT文件足够时就必须安装特殊工具(cygwin,perl,powershell等)?
Mark Lakata

3
BAT在大多数时间就足够了。ppl编写的unix shell脚本的90%不是纯shell,而是具有许多coreutils,sed,awk等调用。GNU已在其他操作系统(包括Windows)中实现了UNIX好东西。因此,请查看此getgnuwin32.sourceforge.net cmd.exe / bash / zsh,这对于大多数任务来说已经足够了。如果您具有BAT / UNIX Shell经验,则没有理由学习所谓的PowerShell
MeaCulpa

0

只有OR部分是棘手的,但是对于包含NOT OR AND的通用布尔表达式,唯一好的解决方案是:

REM if A == B OR C == C then yes

(call :strequ A B || call :strequ C C) && echo yes
exit /b

:strequ
if "%1" == "%2" exit /b 0
exit /b 1

-1

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

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.