Windows 批处理文件中相当于 NEQ、LSS、GTR 等的符号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47385508/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 19:59:57  来源:igfitidea点击:

Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files

windowsbatch-fileif-statementcmd

提问by ditheredtransparency

In batch I always use ==when using the ifcommand. (For example: if "19"=="3" echo My computer doesnt know maths)

在批处理中,我总是==在使用if命令时使用。(例如:if "19"=="3" echo My computer doesnt know maths

What about for all of the others (LSS, LEQ, NEQ, etc.)? Isn't there something like !=for NEQ, or am I thinking Unix?

怎么样对所有其他的(LSSLEQNEQ等)?没有类似!=for 的东西NEQ,还是我在想 Unix?

The reason I want to use symbols is because I thought someone had said for either text or numbers symbols were more efficient than using the text variants.

我想使用符号的原因是因为我认为有人说文本或数字符号比使用文本变体更有效。

Either way, I'd still like to know. Thanks.

不管怎样,我还是想知道。谢谢。

回答by Burhan Khalid

The reason operators like >are not used is because they have special meanings in shell scripts. The >is used to redirect output; <used to redirect input, etc.

>不使用运算符 like 的原因是因为它们在 shell 脚本中具有特殊含义。所述>用于重定向输出; <用于重定向输入等。

The documentation from Microsoft, lists the following operators:

Microsoft文档列出了以下运算符:

Operator | Description
EQU      | equal to
NEQ      | not equal to
LSS      | less than
LEQ      | less than or equal to
GTR      | greater than
GEQ      | greater than or equal to

In addition the word notis used to negate a condition.

此外,该词not用于否定条件。

The reason I want to use symbols is because I thought someone had said for either text or numbers symbols were more efficent than using the text variants.

我想使用符号的原因是因为我认为有人说文本或数字符号比使用文本变体更有效。

They were probably referring to bash and its large catalogof operators. It provides different operators for integer and string operands.

他们可能指的是 bash 及其庞大的运算符目录。它为整数和字符串操作数提供了不同的运算符。

回答by Mofi

The Windows command processor internal command IFhas by default only two operators:

Windows 命令处理器内部命令IF默认只有两个操作符:

  1. ==which runs a stringcomparison of the two arguments on equality, i.e. use strcmpwith condition being trueon strcmpreturning 0.
  2. notin combination with ==to invert the result of the string comparison on equality, i.e. the condition is trueif the two compared strings are notequal.
  1. ==它运行对相等的两个参数的字符串比较,即在返回 0 时使用条件为真的strcmpstrcmp
  2. not结合==以反转字符串比较的结果是否相等,即如果两个比较的字符串相等,则条件为

So the command line

所以命令行

if "19"=="3" echo My computer doesn't know maths

runs strcmpwith the strings "19"and "3"which means the compared byte streams are hexadecimal 22 31 39 22 00and 22 33 22 00. The double quotes are not removed before running?the string comparison. The quotes are included in the string comparison.

运行strcmp与琴弦"19""3"该装置所比较的字节流是十六进制的22 31 39 22 0022 33 22 00。双引号在运行之前不会被删除?字符串比较。引号包含在字符串比较中

A help for command IFis output on running in a command promptwindow the command if /?. This help explains all options and additional operators which can be used on having command extensions enabled as by default.

命令提示符窗口中运行命令IF 时会输出命令IF的帮助。本帮助解释了默认情况下可用于启用命令扩展的所有选项和附加运算符。if /?

There is the option /Ito compare the two arguments case-insensitive using stricmpinstead of strcmp.

可以选择/I使用stricmp而不是来比较两个不区分大小写的参数strcmp

Example:

例子:

if /I not "%~1" == "/I" echo First argument is neither /i nor /I.

There are the additional comparison operators EQU, NEQ, LSS, LEQ, GTR, GEQwith enabled command extensions.

有额外的比较操作符EQUNEQLSSLEQGTRGEQ启用命令扩展

The angle brackets <and >are used on Windows command line as redirection operators. So they can't be used as comparison operators on an IFcondition. Also exclamation mark !is not available as?operator because it means begin/end of an environment variable reference on having delayed environment variable expansion enabled. Run set /?and setlocal /?and endlocal /?for details?on usage of delayed environment variable expansion.

尖括号<>在 Windows 命令行上用作重定向运算符。因此它们不能用作IF条件的比较运算符。感叹号!也不能用作?operator,因为它意味着在启用延迟环境变量扩展时环境变量引用的开始/结束。运行set /?以及setlocal /?endlocal /?对细节?对延迟的环境变量扩展的使用。

Windows command interpreter tries to convert both argument strings to signed 32-bit integers using strtolwith base0 (automatic detection of base) on usage of EQU, NEQ, LSS, LEQ, GTR, GEQ. An integer comparison is done if that is successful for both argument strings because the two compared strings are

Windows 命令解释器尝试使用strtol将两个参数字符串转换为带base0(自动检测基数)的有符号 32 位整数,以使用EQU, NEQ, LSS, LEQ, GTR, GEQ。如果两个参数字符串都成功,则完成整数比较,因为两个比较的字符串是

  • decimal numbers with first character being optionally -or +and all other characters are decimal digits 0123456789with first digit not being 0like -2147483648, -200, +10, 32, 2147483647, or
  • hexadecimal numbers with first character being optionally -or +and next with 0xor 0Xand all?other characters are hexadecimal digits 0123456789ABCDEFabcdeflike -0x80000000, -0XC8, +0x0a, 0x20, 0x7fffFFFF, or
  • octal numbers with first character being optionally -or +and next 0and all other characters are?octal digits 01234567like -020000000000, -0310, +012, 040, 017777777777.
  • 十进制数字的第一个字符是可选的-+,所有其他字符都是十进制数字0123456789,第一个数字不是0-2147483648, -200, +10, 32, 2147483647, 或
  • 十六进制数字的第一个字符是可选的-or+和下一个字符是0xor0X和所有?其他字符是十六进制数字,0123456789ABCDEFabcdef-0x80000000, -0XC8, +0x0a, 0x20, 0x7fffFFFF, or
  • 八进制数字的第一个字符是可选的-+和下一个0,所有其他字符都是八进制数字,01234567-020000000000, -0310, +012, 040, 017777777777

Otherwise the two argument strings are compared again with strcmpor with stricmpon using additionally /Iwith operator EQU, NEQ, LSS, LEQ, GTR, GEQand the comparison operator is applied on the integer result of the string comparison function.

否则,两个参数字符串将再次与strcmpstricmpon 进行比较,另外/I使用运算符EQU, NEQ, LSS, LEQ, GTR,GEQ并将比较运算符应用于字符串比较函数的整数结果。

Note:08and 09like other by people interpreted decimal numbers with one or more leading 0containing 8or 9are interpreted as invalid octal numbers and therefore result in a string instead of an?integer comparison.

注意:0809其他人一样解释十进制数,其中一个或多个前导0包含8或被9解释为无效的八进制数,因此导致字符串而不是整数比较。

The conversion of both string arguments to signed 32-bit integers needs some extra processor instructions (some nanoseconds or microseconds depending on CPU performance). An integer comparison is therefore a bit slower, but usually not really noticeable slower.

将两个字符串参数转换为有符号的 32 位整数需要一些额外的处理器指令(一些纳秒或微秒取决于 CPU 性能)。因此,整数比较会慢一点,但通常不会明显变慢。

Examples:

例子:

if 014 EQU 12 echo Octal number 014 is equal decimal number 12.
if 0x0C EQU 12 echo Hexadecimal number 0C is equal decimal number 12.
if /I 0X0C EQU 014 Hexadecimal number 0C is equal octal number 014.

The option /Iis ignored on using a comparison operator other than ==and both strings can be converted successfully to 32-bit signed integers. This is proven by the third line above. /Iis taken only into account on using the operators EQU, NEQ, LSS, LEQ, GTR, GEQif one of the two strings cannot be converted successfully to an integer like in the following example:

该选项/I在使用比较运算符时被忽略,==并且两个字符串都可以成功转换为 32 位有符号整数。上面的第三行证明了这一点。/I仅在使用运算符EQU, NEQ, LSS, LEQ,时才考虑GTRGEQ如果两个字符串之一无法成功转换为整数,如下例所示:

if /I "0X20" EQU "0x20" echo String "0X20" is case-insensitive equal string "0x20".

If one of the two arguments is enclosed in double quotes on usage of EQU, NEQ, LSS, LEQ, GTR, GEQ, or one of the two strings is not a string representing a valid integer number, the comparison is always done with usage of strcmpor stricmpdepending on usage of /I. strcmpand stricmpreturn both an integer as result which can be a negative number, zero, or a positive number. This integer?result is compared with integer value 0according to the used operator.

如果这两个参数中的一个双引号括起来的用法EQUNEQLSSLEQGTRGEQ,或两个字符串的一个是不是代表一个有效的整数字符串,则比较总是与使用情况进行strcmpstricmp取决于用途/Istrcmpstricmp返回一个整数作为结果,它可以是负数、零或正数。0根据所使用的运算符将此整数?结果与整数值进行比较。

Examples:

例子:

if 010 NEQ "10" echo String 010 is not equal string "10".
if "100" LSS "20" echo String "100" is less than string "20".

On second example the second character 1on left side has a lower code value (49 = 0x31) as the second character 2on?right side (50 = 0x32) which results in strcmpreturning a negative value resulting in function result LSS 0being true.

在第二个示例中1,左侧的第二个字符具有较低的代码值 (49 = 0x31) 作为2右侧的第二个字符(50 = 0x32),这导致strcmp返回负值,结果function result LSS 0为真。

Please note that Windows environment variables are always of type string and need to be converted always from string to integer on using integer comparison or integer arithmetic.

请注意,Windows 环境变量始终是字符串类型,并且需要在使用整数比较或整数运算时始终从字符串转换为整数。

It is advisable in most cases to use string1 == string2or not string1 == string2instead of string1 EQU string2or string1 NEQ string2on comparing two strings not representing integer values to use directly strcmpor stricmp. Otherwise on comparing strings with EQUor NEQjust some nanoseconds or microseconds are wasted by letting Windows command processor first use strtolwhich fails to convert one of the two strings to compare and therefore cmd.exeruns next strcmpor stricmpas it would be done immediately on usage of operator ==.

在大多数情况下,建议使用string1 == string2ornot string1 == string2代替string1 EQU string2or string1 NEQ string2on 比较两个不代表整数值的字符串以直接使用strcmpstricmp。否则,通过让 Windows 命令处理器首先使用无法将两个字符串之一转换为比较并因此运行下一个或将在使用 operator 时立即执行,从而将字符串与EQUNEQ仅一些纳秒或微秒进行比较会被浪费。strtolcmd.exestrcmpstricmp==

One more important fact:

还有一个重要的事实:

A string instead of an integer comparison on usage of one of the comparison operators EQU, NEQ, LSS, LEQ, GTR, GEQis processed by cmd.exeon execution of IFcondition only in case of one of the two arguments contains an invalid character. An integer comparison is done nevertheless on an out of range condition like one argument is lower than -2147483648or greater than 2147483647as discussed at weird results with IF.

字符串而不是所述比较运营商之一的使用整数的比较EQUNEQLSSLEQGTRGEQ由加工cmd.exe上的执行IF条件仅在两个参数中的一个的情况下,包含无效字符。尽管如此,仍会在超出范围的条件下进行整数比较,例如一个参数小于-2147483648或大于IF 的奇怪结果中2147483647所讨论的。

The value range limitation can be worked around by comparing two values as strings on which both value strings have the same number of characters. Here is an example to find out if a file has two or more GiB, i.e. file size is 2147483648or more bytes.

值范围限制可以通过将两个值作为字符串进行比较来解决,其中两个值字符串具有相同的字符数。这是一个示例,用于确定文件是否具有两个或更多GiB,即文件大小为2147483648或更多字节。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
if "%~1" == "" ( set "FileName=%~f0" ) else set "FileName=%~1"
for %%I in ("%FileName%") do set "FileSize=000000000000000%%~zI"
if "%FileSize:~-16%" GEQ "0000002147483648" (
    echo "%FileName%" is greater or equal 2 GiB.
) else echo "%FileName%" is less than 2 GiB.
endlocal
pause

The file size of the file of which name is passed to the batch file is assigned to environment variable FileSizeas string with always at least 15 additional zero digits at beginning.

名称被传递到批处理文件的文件的文件大小FileSize作为字符串分配给环境变量,开头总是至少有 15 个额外的零位。

And next is compared the FileSizestring with just last 16 digits with string 0000002147483648representing 2 GiB in bytes. strcmpcompares the two strings of equal length byte by byte whereby each byte of the two compared strings can have only the hexadecimal values 0x30 to 0x39. strcmpreturns immediately with a negative value if the current byte from left string is lower than the current byte from right string which means the file size is lower than 2 GiB. strcmpreturns immediately with a positive value if the current byte from left string is greater than the current byte from right string which means the file size is greater than 2 GiB. strcmpreturns with zero on the two strings are 100% identical which means the file size is exactly 2 GiB.

接下来将FileSize字符串与仅最后 16 位数字进行比较,字符串以0000002147483648字节为单位表示 2 GiB。strcmp逐字节比较两个长度相等的字符串,两个比较字符串的每个字节只能具有 0x30 到 0x39 的十六进制值。strcmp如果左字符串的当前字节小于右字符串的当前字节,则立即返回负值,这意味着文件大小小于 2 GiB。strcmp如果左字符串的当前字节大于右字符串的当前字节,则立即返回正值,这意味着文件大小大于 2 GiB。strcmp在两个字符串上返回零值是 100% 相同的,这意味着文件大小正好是 2 GiB。

Please note that comparing values using a string comparison requires that both values have the same number of characters for an accurate result. The value string with less digits must be prepended with the right amount of 0.

请注意,使用字符串比较来比较值需要两个值具有相同的字符数才能获得准确的结果。数字较少的值字符串必须在前面加上适量的0.