Windows批处理文件中等效于NEQ,LSS,GTR等的符号




batch-file if-statement (2)

Windows内部命令 IF 默认只有两个运算符:

  1. == 运行两个参数相等的 字符串 比较,即在 strcmp 返回0时使用条件为 true strcmp
  2. not== 组合以反转相等的字符串比较结果,即如果两个比较的字符串 相等则条件为

所以命令行:

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

使用字符串 "19""3" 运行 strcmp ,这意味着比较的字节流是十六进制的 22 31 39 22 0022 33 22 00 。 在运行字符串比较之前,不会删除双引号。 它们包含在字符串比较中。

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

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

例:

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

并且通过启用的命令扩展,还有其他比较运算符: EQUNEQLSSLEQGTRGEQ

尖括号 <> 在Windows命令行上用作 重定向运算符 。 因此它们不能在 IF 条件下用作比较运算符。 还有感叹号 ! 不可用作运算符,因为它表示启用了延迟环境变量扩展的环境变量引用的开始/结束。 运行 set /?setlocal /?endlocal /? 有关延迟环境变量扩展的详细信息。

Windows命令解释器尝试使用 strtol 将两个参数字符串转换为带符号的32位整数,并使用 EQUNEQLSSLEQGTRGEQ base 0(自动检测基数)。 如果两个参数字符串成功,则进行整数比较,因为两个比较的字符串是十进制数,或以 0x 十六进制数或以 0 0x 八进制数。 否则,将两个参数字符串再次与 strcmp 进行比较,并将比较运算符应用于此函数的整数结果。

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

例子:

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.

使用除 == 之外的比较运算符时忽略选项 /I 并且两个字符串仅由数字组成,其中第一个字符也可以是解释为减号的连字符。 这可以通过上面的第三行证明。

如果两个参数中的一个用双引号括起来使用 EQUNEQLSSLEQGTRGEQ 或两个字符串中的一个不是表示整数的字符串,则总是使用 strcmpstricmp 取决于 /I 用法。 strcmpstricmp 返回一个整数作为结果,可以是负数,零或正数。 根据使用的运算符将该整数结果与整数值 0 进行比较。

例子:

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

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

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

在大多数情况下,建议使用 string1 == string2not string1 == string2 而不是 string1 EQU string2string1 NEQ string2 来比较两个不表示整数值的字符串,以便直接使用 strcmpstricmp 。 否则,在将字符串与 EQUNEQ 进行比较时,通过让Windows命令处理器首次使用 strtol 无法将两个字符串中的一个转换为比较而浪费了一些纳秒或微秒,因此 cmd.exe 运行下一个 strcmpstricmp 因为它会立即执行关于operator ==

一个更重要的事实:

只有在两个参数中的一个包含无效字符的情况下,执行 IF 条件时, cmd.exe 才会处理字符串而不是比较器 EQUNEQLSSLEQGTRGEQ 的整数比较。 然而,在超出范围的条件下进行整数比较,例如一个参数低于 -2147483648 或大于 2147483647 如在 IF的奇怪结果中 所讨论的。

通过将两个值比较为两个值字符串具有相同位数的字符串,可以解决值范围限制。 下面是一个示例,以确定文件是否具有两个或更多 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

传递给批处理文件的文件的文件 FileSize 作为字符串分配给环境变量 FileSize ,并且在开头时始终至少有15个额外的零位数。

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

请注意,使用字符串比较比较值要求两个值具有相同的位数以获得准确的结果。 具有较少位数的值字符串必须以正确的数量 0 前置。

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

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

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

无论哪种方式,我还是想知道。 谢谢。


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

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

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

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

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





cmd