Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files
The internal command IF of Windows command processor has by default only two operators:
==
which runs a string comparison of the two arguments on equality, i.e. use lstrcmpW with condition being true onlstrcmpW
returning 0.not
in combination with==
to invert the result of the string comparison on equality, i.e. the condition is true if the two compared strings are not equal.
So the command line
if "19"=="3" echo My computer doesn't know maths
runs lstrcmpW
with the strings "19"
and "3"
which means the compared byte streams are hexadecimal 22 31 39 22 00
and 22 33 22 00
. The double quotes are not removed before running the string comparison. The quotes are included in the string comparison.
A help for command IF is output on running in a command prompt window the command if /?
. This help explains all options and additional operators which can be used on having enabled the command extensions as by default.
There is the option /I
to compare the two arguments case-insensitive by using lstrcmpiW instead of lstrcmpW
.
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
, GEQ
with enabled command extensions.
The angle brackets <
and >
are used on Windows command line as redirection operators. So they can't be used as comparison operators on an IF condition. The exclamation mark !
is also not available as operator because it means beginning/end of an variable reference on having enabled delayed variable expansion. Run set /?
and setlocal /?
and endlocal /?
for details on usage of delayed variable expansion.
Windows command interpreter tries to convert both argument strings to signed 32-bit integers using wcstol with base
0 (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
- decimal numbers with first character being optionally
-
or+
and all other characters are decimal digits0123456789
with first digit not being0
like-2147483648
,-200
,+10
,32
,2147483647
, or - hexadecimal numbers with first character being optionally
-
or+
and next with0x
or0X
and all other characters are hexadecimal digits0123456789ABCDEFabcdef
like-0x80000000
,-0XC8
,+0x0a
,0x20
,0x7fffFFFF
, or - octal numbers with first character being optionally
-
or+
and next0
and all other characters are octal digits01234567
like-020000000000
,-0310
,+012
,040
,017777777777
.
Otherwise the two argument strings are compared again with lstrcmpW
or with lstrcmpiW
on using additionally /I
with operator EQU
, NEQ
, LSS
, LEQ
, GTR
, GEQ
and the comparison operator is applied on the integer result of the string comparison function.
Note: 08
and 09
like other by people interpreted decimal numbers with one or more leading 0
containing 8
or 9
are interpreted as invalid octal numbers and therefore result in a string instead of an integer comparison.
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.
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 /I
is 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. /I
is taken only into account on using the operators EQU
, NEQ
, LSS
, LEQ
, GTR
, GEQ
if one of the two strings cannot be converted successfully to an integer like in the following example:
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 lstrcmpW
or lstrcmpiW
depending on usage of /I
. lstrcmpW
and lstrcmpiW
return both an integer as result which can be a negative number, zero, or a positive number. This integer result is compared with integer value 0
according to the used operator.
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 1
on left side has a lower code value (49 = 0x31) as the second character 2
on right side (50 = 0x32) which results in lstrcmpW
returning a negative value resulting in function result LSS 0
being true.
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.
It is advisable in most cases to use string1 == string2
or not string1 == string2
instead of string1 EQU string2
or string1 NEQ string2
on comparing two strings not representing integer values to use directly lstrcmpW
or lstrcmpiW
. Otherwise on comparing strings with EQU
or NEQ
just some nanoseconds or microseconds are wasted by letting Windows command processor first use wcstol
which fails to convert one of the two strings to compare and therefore cmd.exe
runs next lstrcmpW
or lstrcmpiW
as it would be done immediately on usage of the string comparison operator ==
.
One more important fact:
A string instead of an integer comparison on usage of one of the comparison operators EQU
, NEQ
, LSS
, LEQ
, GTR
, GEQ
is processed by cmd.exe
on execution of IF condition 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 less than -2147483648
or greater than 2147483647
as discussed at weird results with IF.
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 2147483648
or more bytes.
@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 FileSize
as string with always at least 15 additional zero digits at beginning.
And next is compared the FileSize
string with just last 16 digits with string 0000002147483648
representing 2 GiB in bytes. lstrcmpW
compares the two strings of equal length byte by byte whereby each byte of the two compared strings within the also compared double can have only the hexadecimal values 0x30 to 0x39. lstrcmpW
returns immediately with a negative value if the current byte from left string is less than the current byte from right string which means the file size is less than 2 GiB. lstrcmpW
returns 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. lstrcmpW
returns with zero on the two strings are 100% identical which means the file size is exactly 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
.
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.
The documentation from Microsoft lists the following operators:
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 not
is used to negate a condition.
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.
They were probably referring to bash and its large catalog of operators. It provides different operators for integer and string operands.