292

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

4

14 回答 14

338

您可以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
)
于 2010-01-26T23:07:27.833 回答
80

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

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

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

也可以看看:IF /?

于 2010-01-26T22:34:45.333 回答
57

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

这意味着如果名称是“Yakko”或“Wakko”或“Dot”,则回显“Warner Brother or Sister”。

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 的反义词和 is的gtr反义词。)geqlss

set res=true
if %hour% gtr 6 if %hour% lss 22 set res=false
if "%res%"=="true" set state=asleep
于 2012-05-16T04:09:59.710 回答
7

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
于 2012-07-23T03:50:19.860 回答
6

以下示例显示了如何创建 AND 语句(用于设置变量或包含命令的参数)。

启动记事本并关闭 CMD 窗口:

start notepad.exe & exit

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

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

希望有帮助!

于 2011-11-30T19:48:35.810 回答
3

如果您有兴趣在一个语句中写一个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

更统一的版本:

@echo off

setlocal

set "A=1" & set "B=2" & ( call :IF_AND "%%A%% EQU 1" "%%B%% EQU 2" && echo TRUE+ ) || echo FALSE-
set "A=1" & set "B=3" & ( call :IF_AND "%%A%% EQU 1" "%%B%% EQU 2" && echo TRUE+ ) || echo FALSE-
set "A=2" & set "B=2" & ( call :IF_AND "%%A%% EQU 1" "%%B%% EQU 2" && echo TRUE+ ) || echo FALSE-
set "A=2" & set "B=3" & ( call :IF_AND "%%A%% EQU 1" "%%B%% EQU 2" && echo TRUE+ ) || echo FALSE-

echo.

set "A=1" & set "B=2" & ( call :IF_OR "%%A%% EQU 1" "%%B%% EQU 2" && echo TRUE+ ) || echo FALSE-
set "A=1" & set "B=3" & ( call :IF_OR "%%A%% EQU 1" "%%B%% EQU 2" && echo TRUE+ ) || echo FALSE-
set "A=2" & set "B=2" & ( call :IF_OR "%%A%% EQU 1" "%%B%% EQU 2" && echo TRUE+ ) || echo FALSE-
set "A=2" & set "B=3" & ( call :IF_OR "%%A%% EQU 1" "%%B%% EQU 2" && echo TRUE+ ) || echo FALSE-

exit /b 0

:IF_OR
if %~1 ( exit /b 0 ) else if %~2 ( exit /b 0 ) else exit /b 1
exit /b -1

:IF_AND
if %~1 ( if %~2 ( exit /b 0 ) else exit /b 1 ) else exit /b 1
exit /b -1

输出

TRUE+
FALSE-
FALSE-
FALSE-
    
TRUE+
TRUE+
TRUE+
FALSE-

诀窍在于type删除/设置的命令,errorlevel因此处理下一个命令的方式。

于 2017-07-22T14:50:43.693 回答
2

Athul Prakash(当时 16 岁)通过否定 IF 语句中的条件,然后使用 ELSE 子句作为放置需要执行的代码的位置,给出了如何实现 OR 测试的合乎逻辑的想法。我心想,通常需要两个 else 子句,因为他建议使用两个 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
于 2015-08-17T11:47:17.880 回答
2

就像以下一样简单:

与> 如果+如果

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

或 > 如果 // 如果

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*

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

于 2015-12-22T19:38:47.307 回答
1

尝试否定操作数 - 'not'!

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

如果您还没有完全理解,请继续阅读。否则,请不要浪费您的时间并重新开始编程。

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

即使嵌套的“如果不是”中的任何一个条件为真,整个语句仍然不满足。因此,您可以通过记住如果所有嵌套条件都为假,条件语句的主体应该是您想要执行的操作,可以连续使用否定的 'if's。您实际想要提供的主体应该在 else 语句下。

如果你仍然没有明白事情的要点,对不起,我 16 岁,这是我能做的最好的解释。

于 2014-04-22T15:08:22.760 回答
0

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

ķ

于 2010-01-26T23:16:08.920 回答
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
于 2020-04-22T17:06:18.333 回答
0

很多人似乎错过了 OR 最明显的解决方案,即使用标签。

if "%a%" == "ONE" goto do_thing
if "%a%" == "TWO" (
   :do_thing
   echo a is equal to ONE or TWO
)
于 2021-12-15T18:12:19.327 回答
0

如果您需要 else 子句,则可以使用以下语法:

和:

if %v1% == a (if %v2% == b (echo yes) else echo no) else echo no

或者:

if %v1% == a (echo yes) else (if %v2% == b (echo yes) else echo no)
于 2021-12-28T16:41:05.003 回答
-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
于 2017-09-21T22:28:29.160 回答