windows 如果...或如果...在Windows批处理文件中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8438511/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
IF... OR IF... in a windows batch file
提问by Mechaflash
Is there a way to write an IF OR IF conditional statement in a windows batch-file?
有没有办法在 Windows 批处理文件中编写 IF OR IF 条件语句?
For example:
例如:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
回答by dbenham
The zmbq solution is good, but cannot be used in all situations, such as inside a block of code like a FOR DO(...) loop.
zmbq 解决方案很好,但不能在所有情况下使用,例如在像 FOR DO(...) 循环这样的代码块内。
An alternative is to use an indicator variable. Initialize it to be undefined, and then define it only if any one of the OR conditions is true. Then use IF DEFINED as a final test - no need to use delayed expansion.
另一种方法是使用指示变量。将其初始化为 undefined,然后仅当 OR 条件之一为真时才定义它。然后使用 IF DEFINED 作为最终测试 - 无需使用延迟扩展。
FOR ..... DO (
set "TRUE="
IF cond1 set TRUE=1
IF cond2 set TRUE=1
IF defined TRUE (
...
) else (
...
)
)
You could add the ELSE IF logic that arasmussen uses on the grounds that it might perform a wee bit faster if the 1st condition is true, but I never bother.
您可以添加 arasmussen 使用的 ELSE IF 逻辑,因为如果第一个条件为真,它的执行速度可能会快一点,但我从不打扰。
Addendum- This is a duplicate question with nearly identical answers to Using an OR in an IF statement WinXP Batch Script
附录- 这是一个重复的问题,与在 IF 语句 WinXP 批处理脚本中使用 OR 的答案几乎相同
Final addendum- I almost forgot my favorite technique to test if a variable is any one of a list of case insensitive values. Initialize a test variable containing a delimitted list of acceptable values, and then use search and replace to test if your variable is within the list. This is very fast and uses minimal code for an arbitrarily long list. It does require delayed expansion (or else the CALL %%VAR%% trick). Also the test is CASE INSENSITIVE.
最终附录- 我几乎忘记了我最喜欢的测试变量是否是不区分大小写值列表中的任何一个的技术。初始化包含可接受值的分隔列表的测试变量,然后使用搜索和替换来测试您的变量是否在列表中。这非常快,并且对任意长的列表使用最少的代码。它确实需要延迟扩展(或者 CALL %%VAR%% 技巧)。此外,该测试不区分大小写。
set "TEST=;val1;val2;val3;val4;val5;"
if "!TEST:;%VAR%;=!" neq "!TEST!" (echo true) else (echo false)
The above can fail if VAR contains =
, so the test is not fool-proof.
如果 VAR 包含=
,则上述方法可能会失败,因此该测试并非万无一失。
If doing the test within a block where delayed expansion is needed to access current value of VAR then
如果在需要延迟扩展以访问 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)
)
FOR options like "delims=" might be needed depending on expected values within VAR
根据 VAR 中的预期值,可能需要诸如“delims=”之类的 FOR 选项
The above strategy can be made reliable even with =
in VAR by adding a bit more code.
=
通过添加更多代码,即使在 VAR 中,上述策略也可以变得可靠。
set "TEST=;val1;val2;val3;val4;val5;"
if "!TEST:;%VAR%;=!" neq "!TEST!" if "!TEST:;%VAR%;=;%VAR%;"=="!TEST!" echo true
But now we have lost the ability of providing an ELSE clause unless we add an indicator variable. The code has begun to look a bit "ugly", but I think it is the best performing reliable method for testing if VAR is any one of an arbitrary number of case-insensitive options.
但是现在我们已经失去了提供 ELSE 子句的能力,除非我们添加一个指示变量。代码开始看起来有点“难看”,但我认为这是测试 VAR 是否是任意数量的不区分大小写选项中的任何一个的性能最佳的可靠方法。
Finally there is a simpler version that I think is slightly slower because it must perform one IF for each value. Aacini provided this solution in a comment to the accepted answer in the before mentioned link
最后还有一个更简单的版本,我认为它稍微慢一些,因为它必须为每个值执行一个 IF。Aacini 在对上述链接中已接受答案的评论中提供了此解决方案
for %%A in ("val1" "val2" "val3" "val4" "val5") do if "%VAR%"==%%A do echo true
The list of values cannot include the * or ? characters, and the values and %VAR%
should not contain quotes. Quotes lead to problems if the %VAR%
also contains spaces or special characters like ^
, &
etc. One other limitation with this solution is it does not provide the option for an ELSE clause unless you add an indicator variable. Advantages are it can be case sensitive or insensitive depending on presence or absence of IF /I
option.
值列表不能包含 * 或 ? 字符和值,%VAR%
不应包含引号。如果%VAR%
还包含空格或特殊字符(如 等)^
,引号会导致问题&
。此解决方案的另一个限制是它不提供 ELSE 子句的选项,除非您添加指示符变量。优点是它可以区分大小写或不区分大小写,具体取决于 IF/I
选项的存在与否。
回答by zmbq
I don't think so. Just use two IFs and GOTO the same label:
我不这么认为。只需使用两个 IF 和 GOTO 相同的标签:
IF cond1 GOTO foundit
IF cond2 GOTO foundit
ECHO Didn't found it
GOTO end
:foundit
ECHO Found it!
:end
回答by Cactus
Thanks for this post, it helped me a lot.
感谢这篇文章,对我帮助很大。
Dunno if it can help but I had the issue and thanks to you I found what I think is another way to solve it based on this boolean equivalence:
不知道它是否有帮助,但我遇到了这个问题,多亏了你,我发现了另一种基于布尔等价的解决方法:
"A or B" is the same as "not(not A and not B)"
"A or B" 与 "not(not A and not B)" 相同
Thus:
因此:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
Becomes:
变成:
IF not [%var%] == [1] IF not [%var%] == [2] ECHO FALSE
回答by Apostolos
A simple "FOR" can be used in a single line to use an "or" condition:
可以在一行中使用简单的“FOR”来使用“或”条件:
FOR %%a in (item1 item2 ...) DO IF {condition_involving_%%a} {execute_command}
Applied to your case:
适用于您的案例:
FOR %%a in (1 2) DO IF %var%==%%a ECHO TRUE
回答by dognose
Even if this question is a little older:
即使这个问题有点老:
If you want to use if cond1 or cond 2
- you should not use complicated loops or stuff like that.
如果你想使用if cond1 or cond 2
- 你不应该使用复杂的循环或类似的东西。
Simple provide both ifs
after each other combined with goto
- that's an implicit or.
简单地同时提供两者ifs
相结合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
Without goto but an "inplace" action, you might execute the action 3 times, if ALL conditions are matching.
没有 goto 而是一个“就地”操作,如果所有条件都匹配,您可能会执行该操作 3 次。
回答by Andrew Rasmussen
There is no IF <arg> OR
or ELIF
or ELSE IF
in Batch, however...
没有IF <arg> OR
或ELIF
或ELSE IF
批处理,但是...
Try nesting the other IF's inside the ELSE of the previous IF.
尝试将其他 IF 嵌套在前一个 IF 的 ELSE 中。
IF <arg> (
....
) ELSE (
IF <arg> (
......
) ELSE (
IF <arg> (
....
) ELSE (
)
)
回答by bogdan
The goal can be achieved by using IFs indirectly.
该目标可以通过间接使用 IF 来实现。
Below is an example of a complex expression that can be written quite concisely and logically in a CMD batch, without incoherent labels and GOTOs.
下面是一个复杂表达式的例子,它可以在 CMD 批处理中非常简洁和合乎逻辑地编写,没有不连贯的标签和 GOTO。
Code blocks between () brackets are handled by CMD as a (pathetic) kind of subshell. Whatever exit code comes out of a block will be used to determine the true/false value the block plays in a larger boolean expression. Arbitrarily large boolean expressions can be built with these code blocks.
() 括号之间的代码块由 CMD 处理为一种(可悲的)子外壳。无论来自块的退出代码都将用于确定块在更大的布尔表达式中播放的真/假值。可以使用这些代码块构建任意大的布尔表达式。
Simple example
简单的例子
Each block is resolved to true (i.e. ERRORLEVEL = 0 after the last statement in the block has executed) / false, until the value of the whole expression has been determined or control jumps out (e.g. via GOTO):
每个块被解析为真(即在块中的最后一条语句执行后 ERRORLEVEL = 0)/假,直到整个表达式的值已确定或控制跳出(例如通过 GOTO):
((DIR c:\xsgdde /w) || (DIR c:\ /w)) && (ECHO -=BINGO=-)
Complex example
复杂的例子
This solves the problem raised initially. Multiple statements are possible in each block but in the || || || expression it's preferable to be concise so that it's as readable as possible. ^ is an escape char in CMD batches and when placed at the end of a line it will escape the EOL and instruct CMD to continue reading the current batch of statements on the next line.
这就解决了最初提出的问题。每个块中可能有多个语句,但在 || 中 || || 表达最好是简洁的,以便它尽可能地可读。^ 是 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
回答by jeb
It's possible to use a function, which evaluates the OR logic and returns a single value.
可以使用一个函数来评估 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
)
回答by coltonon
If %x%==1 (
If %y%==1 (
:: both are equal to 1.
)
)
That's for checking if multiple variables equal value. Here's for either variable.
那是为了检查多个变量是否相等。这是任何一个变量。
If %x%==1 (
:: true
)
If %x%==0 (
If %y%==1 (
:: true
)
)
If %x%==0 (
If %y%==0 (
:: False
)
)
I just thought of that off the top if my head. I could compact it more.
如果我的头,我只是想到了这一点。我可以更压缩它。
回答by AKAJim
I realize this question is old, but I wanted to post an alternate solution in case anyone else (like myself) found this thread while having the same question. I was able to work around the lack of an OR operator by echoing the variable and using findstr to validate.
我意识到这个问题很旧,但我想发布一个替代解决方案,以防其他人(如我自己)在遇到相同问题时发现此线程。我能够通过回显变量并使用 findstr 进行验证来解决缺少 OR 运算符的问题。
for /f %%v in ('echo %var% ^| findstr /x /c:"1" /c:"2"') do (
if %errorlevel% equ 0 echo true
)