如何在DOS批处理文件中实现逻辑操作符?


当前回答

Athul Prakash (age 16 at the time) gave a logical idea for how to implement an OR test by negating the conditions in IF statements and then using the ELSE clause as the location to put the code that requires execution. I thought to myself that there are however two else clauses usually needed since he is suggesting using two IF statements, and so the executed code needs to be written twice. However, if a GOTO is used to skip past the required code, instead of writing ELSE clauses the code for execution only needs to be written once.

下面是一个可测试的例子,我将如何实现Athul Prakash的否定逻辑来创建一个OR。

在我的例子中,如果某人有坦克执照或者正在服兵役,他就可以开坦克。在两个提示中输入true或false,你将能够看到逻辑是否允许你驾驶坦克。

@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 "%VAR1%"=="VALUE" if "%VAR2%"=="VALUE" *do something*

OR> if // if

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*

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

德摩根定律允许我们只使用连词(“与”)和否定(“非”)将析取(“或”)转换为逻辑等价。这意味着我们可以将析取(“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”示例的另一个版本,但条件被链接到一行上。(注意leq的反义词是gtr, geq的反义词是lss。)

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

如果你有兴趣在一个语句中写一个If +AND/OR,那么它没有任何一个。但是,你仍然可以将if与&&/||和(/)语句组合在一起,以实现你想在一行中w/o任何额外变量和w/o if-else块复制(TRUE和FALSE代码段的单个echo命令):

@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,从而处理到下一个命令的方式。

IF语句不支持逻辑运算符AND和OR。 级联IF语句构成隐式连词:

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

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

参见:IF /?

如果你需要else子句,你可以使用下面的语法:

AND:

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

OR:

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