例如:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
zmbq的解决方案不错,但不能在所有情况下使用,比如在代码块中,比如FOR DO(...)循环。
另一种替代方法是使用指示变量。将其初始化为未定义,只有在任何一个OR条件为真时才定义它。然后使用IF DEFINED作为最终测试 - 不需要使用延迟扩展。
FOR ..... DO (
set "TRUE="
IF cond1 set TRUE=1
IF cond2 set TRUE=1
IF defined TRUE (
...
) else (
...
)
)
你可以添加类似于arasmussen使用的ELSE IF逻辑,因为如果第一个条件为真,它可能会稍微快一点,但我从不费心。
补充说明 - 这是一个重复的问题,几乎与在WinXP批处理脚本中使用OR的IF语句具有相同的答案。
最后补充 - 我差点忘记了我的最喜欢的测试变量是否为任何一组不区分大小写的值的技巧。初始化一个包含可接受值列表的测试变量,然后使用搜索和替换来测试您的变量是否在列表内。这非常快速,并且对于任意长的列表使用极少的代码。它需要延迟展开(或者使用CALL %%VAR%%技巧)。此外,测试不区分大小写。
set "TEST=;val1;val2;val3;val4;val5;"
if "!TEST:;%VAR%;=!" neq "!TEST!" (echo true) else (echo false)
如果 VAR 包含 =
,那么上述方法可能会失败,因此测试并不是万无一失的。
如果在需要延迟扩展以访问 VAR 的当前值的块中进行测试,则:
for ... do (
set "TEST=;val1;val2;val3;val4;val5;"
for /f %%A in (";!VAR!;") do if "!TEST:%%A=!" neq "!TEST!" (echo true) else (echo false)
)
根据 VAR 中预期的值,可能需要像 "delims=" 这样的选项。
通过添加更多的代码,即使在 VAR 中含有 =
,也可以使上述策略变得可靠。
set "TEST=;val1;val2;val3;val4;val5;"
if "!TEST:;%VAR%;=!" neq "!TEST!" if "!TEST:;%VAR%;=;%VAR%;"=="!TEST!" echo true
但是现在我们失去了提供ELSE子句的能力,除非我们添加一个指示变量。代码开始看起来有点“丑陋”,但我认为这是用于测试VAR是否为任意大小写选项之一的最佳性能可靠方法。
最后有一个更简单的版本,我认为它稍微慢一些,因为它必须为每个值执行一个IF。Aacini在上述链接的已接受答案的评论中提供了此解决方案。
for %%A in ("val1" "val2" "val3" "val4" "val5") do if "%VAR%"==%%A echo true
该值列表不能包含 * 或 ? 字符,而且值和 %VAR%
不应包含引号。如果 %VAR%
包含空格或特殊字符如 ^
, &
等,则引号会导致问题。此解决方法的另一个限制是,除非添加指示变量,否则它不提供 ELSE 子句选项。优点是,它可以基于 IF /I
选项的存在或缺失来区分大小写。
我不这么认为。只需使用两个IF语句并跳转到同一个标签:
IF cond1 GOTO foundit
IF cond2 GOTO foundit
ECHO Didn't find it
GOTO end
:foundit
ECHO Found it!
:end
使用简单的“FOR”循环可以在一行中使用“or”条件:
FOR %%a in (item1 item2 ...) DO IF {condition_involving_%%a} {execute_command}
适用于您的情况:
FOR %%a in (1 2) DO IF %var%==%%a ECHO TRUE
有评论指出可能会出现{execute_command}
两次执行的情况。为了避免这种情况,您可以在第一次执行后使用goto命令。
FOR %%a in (1 2) DO IF %var%==%%a (
ECHO TRUE
goto :continue
)
:continue
如果你觉得有可能会执行两次 {execute_command}
,而且你不希望这样,你可以添加 && goto :eof
:
FOR %%a in (1 2) DO IF %var%==%%a ECHO TRUE && goto :eof
更简单了,而且仍然在一行上。
谢谢您发布这篇文章,它对我很有帮助。
不知道这是否能帮助,但我也遇到了这个问题,由于您的帮助,我发现了另一种基于布尔等价性解决它的方法:
“A或B”的结果与“非(非A且非B)”相同。
因此:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
变成:
IF not [%var%] == [1] IF not [%var%] == [2] ECHO FALSE
if cond1 or cond2
,你不应该使用复杂的循环或类似的东西。简单地将两个if
结合goto
放在一起即可——这是一个隐式的或。//thats an implicit IF cond1 OR cond2 OR cond3
if cond1 GOTO doit
if cond2 GOTO doit
if cond3 GOTO doit
//thats our else.
GOTO end
:doit
echo "doing it"
:end
如果没有使用goto但是采用“就地”操作,如果所有条件都匹配,则可能会执行该操作3次。
IF <arg> OR
、ELIF
或ELSE IF
语句,但是可以尝试将其他的IF语句嵌套在前一个IF的ELSE语句中。IF <arg> (
....
) ELSE (
IF <arg> (
......
) ELSE (
IF <arg> (
....
) ELSE (
)
)
((DIR c:\xsgdde /w) || (DIR c:\ /w)) && (ECHO -=BINGO=-)
复杂示例
这解决了最初提出的问题。每个块中可能有多个语句,但在 || || || 表达式中,尽可能简洁以使其易读性更强。^ 是CMD批处理中的转义字符,当放置在行末时,它将转义EOL并指示CMD继续在下一行上读取当前批处理语句。
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
(
(CALL :ProcedureType1 a b) ^
|| (CALL :ProcedureType2 sgd) ^
|| (CALL :ProcedureType1 c c)
) ^
&& (
ECHO -=BINGO=-
GOTO :EOF
)
ECHO -=no bingo for you=-
GOTO :EOF
:ProcedureType1
IF "%~1" == "%~2" (EXIT /B 0) ELSE (EXIT /B 1)
GOTO :EOF (this line is decorative as it's never reached)
:ProcedureType2
ECHO :ax:xa:xx:aa:|FINDSTR /I /L /C:":%~1:">nul
GOTO :EOF
可以使用一个函数来评估OR逻辑并返回单个值。
@echo off
set var1=3
set var2=5
call :logic_or orResult "'%var1%'=='4'" "'%var2%'=='5'"
if %orResult%==1 (
echo At least one expression is true
) ELSE echo All expressions are false
exit /b
:logic_or <resultVar> expression1 [[expr2] ... expr-n]
SETLOCAL
set "logic_or.result=0"
set "logic_or.resultVar=%~1"
:logic_or_loop
if "%~2"=="" goto :logic_or_end
if %~2 set "logic_or.result=1"
SHIFT
goto :logic_or_loop
:logic_or_end
(
ENDLOCAL
set "%logic_or.resultVar%=%logic_or.result%"
exit /b
)
&& ... || ...
语法,而不需要额外的IF ... ELSE ...
语句。 - dbenham虽然没有OR运算符,但你可以写(伪代码)
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
喜欢
IF "%var%" == "1" SET "match=y"
IF "%var%" == "2" SET "match=y"
IF DEFINED match ECHO TRUE
If %x%==1 (
If %y%==1 (
:: both are equal to 1.
)
)
If %x%==1 (
:: true
)
If %x%==0 (
If %y%==1 (
:: true
)
)
If %x%==0 (
If %y%==0 (
:: False
)
)
IF [%var%]==[1] IF [%var2%]==[2] ECHO BOTH ARE TRUE
。以前我使用过定义SET AND=IF
,然后编写:IF cond1 %AND% cond2 ECHO BOTH ARE TRUE
的方式。 - Aacini