windows cmd.exe:复杂的条件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2772180/
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
cmd.exe: complex conditions?
提问by shoosh
in DOS batch files, In an IF
statement, is it possible to combine two or more conditions using AND or OR ? I was not able to find any documentation for that
在 DOS 批处理文件中,在IF
语句中,是否可以使用 AND 或 OR 组合两个或多个条件?我找不到任何相关文件
Edit- help if
and the MS docs say nothing about using more than one condition in an if.
编辑-help if
并且 MS 文档没有说明在 if 中使用多个条件。
I guess a workaround for AND would be to do
我想 AND 的一种解决方法是
if COND1 (
if COND2 (
cmd
)
)
but this is exactly what I'm trying to avoid.
但这正是我想要避免的。
采纳答案by Joey
No, there is no easier way.
不,没有更简单的方法。
For and
you can also just chain them without introducing blocks:
因为and
你也可以在不引入块的情况下将它们链接起来:
if COND1 if COND2 ...
which frankly isn't any worse than
坦率地说,这并不比
if COND1 and COND2 ...
However, for or
it gets uglier, indeed:
然而,因为or
它变得更丑,确实:
set COND=
if COND1 set COND=1
if COND2 set COND=1
if defined COND ...
or:
或者:
if COND1 goto :meh
if COND2 goto :meh
goto :meh2
:meh
...
:meh2
I once saw a batch preprocessor which used C-like syntax for control flow and batch stuff in between and then converted such conditionals into multiple jumps and checks. However, that thing was for DOS batch files and was of little to no use in a Windows environment.
我曾经看到一个批处理预处理器,它使用类似 C 的语法进行控制流和批处理,然后将这些条件转换为多个跳转和检查。然而,那个东西是针对 DOS 批处理文件的,在 Windows 环境中几乎没有用。
回答by Mehrdad Mirreza
I sometimes wonder, what people learn at school nowadays! Of course 'OR' is possible too. Any system that can provide you with a 'NOT' and an 'AND', automatically provides you with an 'OR' too, because:
我有时想知道,现在人们在学校学到什么!当然,'OR' 也是可能的。任何可以为您提供“NOT”和“AND”的系统也会自动为您提供“OR”,因为:
x OR y = NOT ( (NOT x) AND (NOT y) )see http://en.wikipedia.org/wiki/De_Morgan%27s_laws
x OR y = NOT ( (NOT x) AND (NOT y) )参见http://en.wikipedia.org/wiki/De_Morgan%27s_laws
So as long as the expression "if (x AND y) then do z" can be written like this:
所以只要表达式“if (x AND y) then do z”可以这样写:
if (x) if (y) (do z)
... we should be able to write the expression "if (x OR y) then do z", butthere is a problem:
...我们应该可以写出表达式“if (x OR y) then do z”,但是有一个问题:
Where shall we put the first 'NOT'? Well, the answer is nowhere, we should reform the equation above first to:
我们应该把第一个“NOT”放在哪里?好吧,答案无处可寻,我们应该首先将上面的等式改造成:
NOT ( x OR y ) = (NOT x) AND (NOT y)
NOT (x OR y) = (NOT x) AND (NOT y)
According to this, we may write "if (NOT(x OR y)) then (do z)" as:
据此,我们可以将“if (NOT(x OR y)) then (do z)”写成:
"if ((NOT x) AND (NOT y)) then (do z)"
“如果((NOT x)AND(NOT y))那么(do z)”
Having this and knowing how to express AND as shown above, we can now write the expression "if (NOT(x OR y)) then (do z)" as:
有了这个并知道如何表达如上所示的 AND,我们现在可以将表达式“if (NOT(x OR y)) then (do z)”写为:
if (not x) if (not y) (REM do z)
We also know that the expression:
我们也知道表达式:
"if (NOT p) then (do q) else (do r)"
“如果(不是 p)那么(做 q)否则(做 r)”
... is equivalent to:
...相当于:
"if (p) then (do r) else (do q)
“如果(p)那么(做r)否则(做q)
Thus we can write for "if (x OR y) then (do z)":
因此我们可以写成“if (x OR y) then (do z)”:
"if (NOT(x OR y)) then (do nothing) else (do z)"
“如果(NOT(x OR y))那么(什么都不做)其他(做z)”
So we can express "if (x OR y) then (do z)"as:
所以我们可以将“if (x OR y) then (do z)”表示为:
if (not x) if (not y) (REM do nothing) else (REM do z)
But this is not complete yet, because this is not a true 'AND' but a "simulated" one. What is missing is the second else. So the complete form to get the correct result should be:
但这还没有完成,因为这不是真正的“与”,而是“模拟”的。缺少的是第二个。所以获得正确结果的完整表格应该是:
if (not x) ( if (not y) (REM do nothing) else (REM do z) ) else (REM do z) )
... which has the ugly double else part. You can solve that with a 'goto' and we finallyhave:
...其中有丑陋的双重 else 部分。你可以用“goto”来解决这个问题,我们终于有了:
rem if (x OR y) then (do z):
if (not x) ( if (not y) (goto :doNothing) )
rem do z
:doNothing
回答by Gilles Maisonneuve
For the AND workaround I agree with Joey, I cannot see another solution.
对于 AND 解决方法,我同意 Joey 的观点,我看不到其他解决方案。
For the OR workaround I would propose the following 'trick':
Lets say that you want to test if user asked for help on the command line while calling for your batch file, something like: thebatch /?
.
But you don't know if the user will type /?
or rather (being a Unix accustomed user) --help
or -h
or even forget to pass any argument at all.
Your code could be like:
对于或变通方法我想提出以下几点建议“绝招”:
比方说,你想测试,如果用户要求在命令行上的帮助,同时呼吁您的批处理文件,是这样的:thebatch /?
。
但你不知道,如果用户将输入/?
或者说(是Unix的习惯用户)--help
或者-h
甚至忘记在所有传递任何参数。
你的代码可能是这样的:
for %%P in ("" "-h" "--help") do if "%1"==%%P (
:help
echo this is my help... >&2
exit /b 9
)
Note however that testing "/?" or "-?" strings won't work with that trick (FOR
loops don't like the ?
meta character).
For that purpose, just add the line: if "%1"=="/?" goto help
on top of the block (see the ':help'
label inside thefor
loop?)
但是请注意测试“/?” 或者 ”-?” 字符串不适用于该技巧(FOR
循环不喜欢?
元字符)。
为此,只需添加行:if "%1"=="/?" goto help
在块的顶部(查看循环内的':help'
标签?)for
Note too that this syntax won't work (it is just completely ignored and code won't be executed) with batch files under TCC.EXE (the Take Command interpreter, either full or lite edition) but in that case just use their syntax with their .OR.
and .AND.
keywords.
还要注意,此语法不适用于 TCC.EXE(Take Command 解释器,完整版或精简版)下的批处理文件(它只是被完全忽略并且不会执行代码),但在这种情况下只需使用它们的语法他们.OR.
和.AND.
关键字。
Hope this helps.
希望这可以帮助。
回答by stealth
If your conditions are checking for specific values of a variable, you might be able to set it up like a CASE statement. I had a need to check if the TYPE was an individual member or a group (or all).
如果您的条件正在检查变量的特定值,您可以像 CASE 语句一样设置它。我需要检查 TYPE 是个人成员还是团体(或全部)。
Note:labels are case insensitive.
注意:标签不区分大小写。
If any of the conditions are true (if TYPE==ALL
or TYPE==GROUP1
or TYPE==GROUP2
), then the code block executes, otherwise execution skips over the block.
如果任何条件为真(如果TYPE==ALL
或TYPE==GROUP1
或TYPE==GROUP2
),则代码块执行,否则执行跳过块。
goto :TYPE_EQ_%TYPE% 2>NUL
if %ERRORLEVEL% neq 0 goto :END_CASE_TYPE
:TYPE_EQ_ALL
:TYPE_EQ_GROUP1
:TYPE_EQ_GROUP2
rem do what you need
echo GROUP: %TYPE%
:END_CASE_TYPE
I don't like Mehrdad's Electrical Engineering (digital electronics)approach. While accurate, with software engineering, the idea, as indicated by the OP, is to make things simpler to figure out. Nested if statements add Complexity (McCabe). Adding extra NOTs doesn't help.
我不喜欢 Mehrdad 的电气工程(数字电子)方法。虽然准确,但对于软件工程,正如 OP 所指出的那样,这个想法是让事情更容易弄清楚。嵌套的 if 语句增加了 Complexity (McCabe)。添加额外的 NOT 没有帮助。
My solution is a little odd if you don't know the goto-label/error set-up, but it's a flat structure that is roughly set up like an if-statement with several OR'd conditions that are not to hard to decipher.
如果您不知道 goto-label/error 设置,我的解决方案有点奇怪,但它是一个平面结构,大致设置为 if 语句,带有几个不难破译的 OR'd 条件.
回答by alecov
AND:
和:
IF <COND1> IF <COND2> ACTION
OR:
或者:
(SET _=) & (IF <COND1> (SET _= ) ELSE IF <COND2> (SET _= )) & IF DEFINED _ ACTION
For implementing OR this way, you do need command extensions.
为了以这种方式实现 OR,您确实需要命令扩展。
回答by Vicky
As long as command extensions are enabled, you can use compare-operators.
只要启用了命令扩展,就可以使用比较运算符。
This is directly pasted from "help if":
这是从“help if”直接粘贴的:
If Command Extensions are enabled IF changes as follows:
如果启用命令扩展,则 IF 更改如下:
IF [/I] string1 compare-op string2 command
IF CMDEXTVERSION number command
IF DEFINED variable command
where compare-op may be one of:
其中 compare-op 可能是以下之一:
EQU - equal
NEQ - not equal
LSS - less than
LEQ - less than or equal
GTR - greater than
GEQ - greater than or equal
and the /I switch, if specified, says to do case insensitive string compares. The /I switch can also be used on the string1==string2 form of IF. These comparisons are generic, in that if both string1 and string2 are both comprised of all numeric digits, then the strings are converted to numbers and a numeric comparison is performed.
并且 /I 开关(如果指定)表示进行不区分大小写的字符串比较。/I 开关也可用于 IF 的 string1==string2 形式。这些比较是通用的,因为如果 string1 和 string2 都由所有数字组成,则将字符串转换为数字并执行数字比较。