不使用运算符 <和> 的原因是因为它们在 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 及其庞大的运算符目录。它为整数和字符串操作数提供了不同的运算符。
Windows 命令处理器内部命令IF默认只有两个操作符:
==
它运行对相等的两个参数的字符串比较,即在返回 0 时使用条件为真的strcmp strcmp
。not
结合==
以反转字符串比较的结果是否相等,即如果两个比较的字符串不相等,则条件为真。所以命令行
if "19"=="3" echo My computer doesn't know maths
运行strcmp
与琴弦"19"
和"3"
该装置所比较的字节流是十六进制的22 31 39 22 00
和22 33 22 00
。在运行字符串比较之前不会删除双引号。引号包含在字符串比较中。
在命令提示符窗口中运行命令IF 时会输出命令IF的帮助if /?
。本帮助解释了默认情况下可用于启用命令扩展的所有选项和附加运算符。
可以选择/I
使用 stricmp 而不是 来比较两个不区分大小写的参数strcmp
。
例子:
if /I not "%~1" == "/I" echo First argument is neither /i nor /I.
有额外的比较操作符EQU
,NEQ
,LSS
,LEQ
,GTR
,GEQ
以启用命令扩展。
尖括号<
和>
在 Windows 命令行上用作重定向运算符。因此它们不能用作IF条件的比较运算符。感叹号!
也不能用作运算符,因为它表示启用延迟环境变量扩展时环境变量引用的开始/结束。运行set /?
和setlocal /?
和endlocal /?
对延迟的环境变量扩展的使用细节。
视窗命令解释试图既参数字符串使用strtol将符号的32位整数转换与base
对使用0(碱的自动检测)EQU
,NEQ
,LSS
,LEQ
,GTR
,GEQ
。如果两个参数字符串都成功,则进行整数比较,因为两个比较的字符串是
-
或+
,所有其他字符都是十进制数字0123456789
,第一个数字不是0
像-2147483648
, -200
, +10
, 32
, 2147483647
, 或-
or+
和下一个字符是0x
or0X
和所有其他字符都是十六进制数字,0123456789ABCDEFabcdef
如-0x80000000
, -0XC8
, +0x0a
, 0x20
, 0x7fffFFFF
, 或-
或+
和下一个0
,所有其他字符都是八进制数字,01234567
如-020000000000
, -0310
, +012
, 040
, 017777777777
。否则,两个参数字符串将再次与strcmp
或 with进行比较,stricmp
另外/I
使用运算符EQU
, NEQ
, LSS
, LEQ
, GTR
,GEQ
并将比较运算符应用于字符串比较函数的整数结果。
注意: 08
和09
其他人一样,人们解释十进制数,其中一个或多个前导0
包含8
或被9
解释为无效的八进制数,因此导致字符串而不是整数比较。
将两个字符串参数转换为有符号的 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
在使用比较运算符时被忽略,==
并且两个字符串都可以成功转换为 32 位有符号整数。上面的第三行证明了这一点。/I
仅在使用运算符EQU
, NEQ
, LSS
, LEQ
,时才考虑GTR
,GEQ
如果两个字符串之一无法成功转换为整数,如下例所示:
if /I "0X20" EQU "0x20" echo String "0X20" is case-insensitive equal string "0x20".
如果这两个参数中的一个双引号括起来的用法EQU
,NEQ
,LSS
,LEQ
,GTR
,GEQ
,或两个字符串的一个是不是代表一个有效的整数字符串,则比较总是与使用情况进行strcmp
或stricmp
取决于用途/I
。strcmp
并stricmp
返回一个整数作为结果,它可以是负数、零或正数。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 == string2
ornot string1 == string2
代替string1 EQU string2
or string1 NEQ string2
on 比较两个不代表整数值的字符串以直接使用strcmp
或stricmp
。否则,通过让 Windows 命令处理器首先使用无法将两个字符串之一转换为比较并因此运行下一个或将在使用运算符时立即执行,从而将字符串与EQU
或NEQ
仅一些纳秒或微秒进行比较会被浪费。strtol
cmd.exe
strcmp
stricmp==
还有一个重要的事实:
字符串而不是所述比较运营商之一的使用整数的比较EQU
,NEQ
,LSS
,LEQ
,GTR
,GEQ
由加工cmd.exe
上的执行IF条件仅在两个参数中的一个的情况下,包含无效字符。尽管如此,还是在超出范围的条件下进行整数比较,例如一个参数小于-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
作为字符串分配给环境变量,开头总是至少有 15 个额外的零位。
接下来将FileSize
字符串与仅最后 16 位数字进行比较,字符串以0000002147483648
字节为单位表示 2 GiB。strcmp
逐字节比较两个长度相等的字符串,两个比较字符串的每个字节只能具有 0x30 到 0x39 的十六进制值。strcmp
如果左字符串的当前字节小于右字符串的当前字节,则立即返回负值,这意味着文件大小小于 2 GiB。strcmp
如果左字符串的当前字节大于右字符串的当前字节,则立即返回正值,这意味着文件大小大于 2 GiB。strcmp
在两个字符串上返回零是 100% 相同的,这意味着文件大小正好是 2 GiB。
请注意,使用字符串比较来比较值需要两个值具有相同的字符数才能获得准确的结果。数字较少的值字符串必须在前面加上适量的0
.