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

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

提问人:ditheredtransparency 提问时间:11/20/2017 最后编辑:Mofiditheredtransparency 更新时间:8/12/2023 访问量:94882

问:

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

那么所有其他(、、等)呢?是不是有类似的东西,或者我在想 Unix?LSSLEQNEQ!=NEQ

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

无论哪种方式,我仍然想知道。谢谢。

Windows 批处理文件 if-statement cmd

评论

2赞 Michael Burr 11/20/2017
您可以使用,但我认为除了 .如果你仔细想想,最有可能的符号已经用于重定向,所以可能需要一些可怕的引用或其他一些奇怪的语法才能使用它们。我不知道为什么他们从未添加对 .if not str1==str2 ...==!=
3赞 Stephan 11/20/2017
@MichaelBurr:可能是因为在使用延迟扩展时,同样可怕的[转义|引用|奇怪的语法]是必要的。

答:

34赞 Burhan Khalid 11/20/2017 #1

之所以不使用运算符 like,是因为它们在 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 及其庞大的运算符目录。它为整数和字符串操作数提供了不同的运算符。

22赞 Mofi 11/20/2017 #2

默认情况下,Windows 命令处理器的内部命令 IF 只有两个运算符:

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

所以命令行

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

与字符串一起运行,这意味着比较的字节流是十六进制的,并且。在运行字符串比较之前,不会删除双引号。引号包含在字符串比较中lstrcmpW"19""3"22 31 39 22 0022 33 22 00

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

可以选择使用 lstrcmpiW 而不是 来比较两个不区分大小写的参数。/IlstrcmpW

例:

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

还有附加的比较运算符 、 、 、 、 、EQUNEQLSSLEQGTRGEQ

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

Windows 命令解释器尝试使用 wcstol 和 0(自动检测基数)将两个参数字符串转换为有符号的 32 位整数,因为 、 、 、 、 。如果两个参数字符串都成功,则进行整数比较,因为两个比较的字符串是baseEQUNEQLSSLEQGTRGEQ

  • 第一个字符可选的十进制数,所有其他字符都是十进制数字,第一个数字不是 、 、 、 或-+01234567890-2147483648-200+10322147483647
  • 第一个字符可选为 OR 的十六进制数,下一个字符为 OR,所有其他字符都是十六进制数字,如 、 、 、 或-+0x0X0123456789ABCDEFabcdef-0x80000000-0XC8+0x0a0x200x7fffFFFF
  • 八进制数,第一个字符是可选的 or 和下一个字符,所有其他字符都是八进制数字,如 、 、 、 。-+001234567-020000000000-0310+012040017777777777

否则,将两个参数字符串再次与 on 或 on 进行比较,另外使用运算符 、 、 、 、 ,并将比较运算符应用于字符串比较函数的整数结果。lstrcmpWlstrcmpiW/IEQUNEQLSSLEQGTRGEQ

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

将两个字符串参数转换为有符号的 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.

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

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

如果两个参数中的一个在用双引号括起来时用双引号括起来,或者两个字符串中的一个不是表示有效整数的字符串,则始终使用 或取决于 的用法进行比较。 并返回一个整数作为结果,它可以是负数、零或正数。根据使用的运算符,将此整数结果与整数值进行比较。EQUNEQLSSLEQGTRGEQlstrcmpWlstrcmpiW/IlstrcmpWlstrcmpiW0

例子:

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

在第二个示例中,左侧的第二个字符具有较低的代码值 (49 = 0x31),因为右侧的第二个字符 (50 = 0x32) 会导致返回负值,从而为 true。12lstrcmpWfunction result LSS 0

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

在大多数情况下,建议使用 or 代替 或 在比较两个不表示整数值的字符串时直接使用 或 。否则,在比较字符串时,让 Windows 命令处理器首先使用或仅使用一些纳秒或微秒,这无法转换要比较的两个字符串之一,因此接下来运行,或者就像使用字符串比较运算符时立即完成的那样。string1 == string2not string1 == string2string1 EQU string2string1 NEQ string2lstrcmpWlstrcmpiWEQUNEQwcstolcmd.exelstrcmpWlstrcmpiW==

另一个重要的事实:

只有在两个参数之一包含无效字符的情况下,才会在执行 IF 条件时处理字符串而不是整数比较,而不是使用其中一个比较运算符 , , , 的整数比较。然而,在超出范围的条件下,例如一个参数小于或大于,如在 IF 的奇怪结果中讨论的那样,还是进行了整数比较。EQUNEQLSSLEQGTRGEQcmd.exe-21474836482147483647

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

将名称传递给批处理文件的文件的文件大小以字符串形式分配给环境变量,开头始终至少包含 15 个额外的零位数字。FileSize

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

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