Símbolo equivalente a NEQ, LSS, GTR, etc. en archivos por lotes de Windows
batch-file if-statement (2)
El comando interno de Windows IF tiene por defecto solo dos operadores:
-
==
que ejecuta una comparación de cadenas de los dos argumentos sobre igualdad, es decir, usa strcmp con la condición verdadera enstrcmp
devuelve 0. -
not
en combinación con==
para invertir el resultado de la comparación de cadenas en igualdad, es decir, la condición es verdadera si las dos cadenas comparadas no son iguales.
Entonces la línea de comando:
if "19"=="3" echo My computer doesn''t know maths
ejecuta
strcmp
con las cadenas
"19"
y
"3"
que significa que las secuencias de bytes comparadas son hexadecimales
22 31 39 22 00
y
22 33 22 00
.
Las comillas dobles no se eliminan antes de ejecutar la comparación de cadenas.
Se incluyen en la comparación de cadenas.
Se muestra una ayuda para el comando
IF
al ejecutarse en una ventana de símbolo del sistema el comando
if /?
.
Esta ayuda explica todas las opciones y operadores adicionales que se pueden usar para habilitar las extensiones de comando de forma predeterminada.
Existe la opción
/I
para comparar los dos argumentos sin distinción entre mayúsculas y minúsculas usando
stricmp
lugar de
strcmp
.
Ejemplo:
if /I not "%~1" == "/I" echo First argument is neither /i nor /I.
Y con las extensiones de comando habilitadas hay operadores de comparación adicionales:
EQU
,
NEQ
,
LSS
,
LEQ
,
GTR
,
GEQ
Los corchetes angulares
<
y
>
se usan en la línea de comandos de Windows como
operadores de redireccionamiento
.
Por lo tanto, no pueden usarse como operadores de comparación en una condición
IF
.
También signo de exclamación
!
no está disponible como operador porque significa comenzar / finalizar una referencia de variable de entorno al tener habilitada la expansión de la variable de entorno retrasada.
Ejecutar
set /?
y
setlocal /?
y
endlocal /?
para detalles sobre la expansión variable de entorno retardado.
El intérprete de comandos de Windows intenta convertir ambas cadenas de argumentos en enteros de 32 bits con
strtol
con
base
0 (detección automática de base) en el uso de
EQU
,
NEQ
,
LSS
,
LEQ
,
GTR
,
GEQ
.
Se realiza una comparación de enteros si eso es exitoso para ambas cadenas de argumentos porque las dos cadenas comparadas son números decimales, o números hexadecimales que comienzan con
0x
o números octales que comienzan con
0
.
De lo contrario, las dos cadenas de argumentos se comparan nuevamente con
strcmp
y el operador de comparación se aplica al resultado entero de esta función.
La conversión de ambos argumentos de cadena a enteros de 32 bits con signo necesita algunas instrucciones adicionales del procesador (algunos nanosegundos o microsegundos, dependiendo del rendimiento de la CPU). Por lo tanto, una comparación de enteros es un poco más lenta, pero no realmente notable más lenta.
Ejemplos:
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.
La opción
/I
se ignora al usar un operador de comparación que no sea
==
y ambas cadenas consisten solo en dígitos numéricos por lo que el primer carácter también puede ser un guión interpretado como un signo menos.
Esto está demostrado por la tercera línea anterior.
Si uno de los dos argumentos está entre comillas dobles sobre el uso de
EQU
,
NEQ
,
LSS
,
LEQ
,
GTR
,
GEQ
, o una de las dos cadenas no es una cadena que representa un número entero, la comparación siempre se realiza con el uso de
strcmp
o
stricmp
dependiendo del uso de
/I
strcmp
y
stricmp
devuelven un número entero como resultado que puede ser un número negativo, cero o un número positivo.
Este resultado entero se compara con el valor entero
0
según el operador utilizado.
Ejemplos:
if 010 NEQ "10" echo String 010 is not equal string "10".
if "100" LSS "20" echo String "100" is less than string "20".
El segundo carácter
1
en el lado izquierdo tiene un valor de código más bajo (49 = 0x31) como segundo carácter
2
en el lado derecho (50 = 0x32), lo que da como resultado que
strcmp
devuelva un valor negativo, lo que hace que el resultado de la
function result LSS 0
sea verdadero.
Tenga en cuenta que las variables de entorno de Windows son siempre de tipo cadena y deben convertirse siempre de cadena a entero utilizando la comparación de enteros o la aritmética de enteros.
En la mayoría de los casos, es aconsejable utilizar
string1 == string2
o
not string1 == string2
lugar de
string1 EQU string2
o
string1 NEQ string2
al comparar dos cadenas que no representan valores enteros para usar directamente
strcmp
o
stricmp
.
De lo contrario, al comparar cadenas con
EQU
o
NEQ
solo se desperdician algunos nanosegundos o microsegundos al permitir que el procesador de comandos de Windows use primero
strtol
que no puede convertir una de las dos cadenas para comparar y, por lo tanto,
cmd.exe
ejecuta el siguiente
strcmp
o
stricmp
como se haría inmediatamente sobre el uso del operador
==
.
Un hecho más importante:
cmd.exe
procesa una cadena en lugar de una comparación de enteros sobre el uso de los comparadores
EQU
,
NEQ
,
LSS
,
LEQ
,
GTR
,
GEQ
en la ejecución de la condición
IF
solo en el caso de que uno de los dos argumentos contenga un carácter no válido.
Sin embargo, se realiza una comparación de enteros en una condición fuera de rango como un argumento es menor que
-2147483648
o mayor que
2147483647
como se discute en
resultados extraños con IF
.
La limitación del rango de valores se puede resolver comparando dos valores como cadenas en las que ambas cadenas de valores tienen el mismo número de dígitos.
Aquí hay un ejemplo para averiguar si un archivo tiene dos o más
GiB
, es decir, el tamaño del archivo es
2147483648
o más 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
El tamaño del archivo cuyo nombre se pasa al archivo por lotes se asigna a la variable de entorno
FileSize
como cadena con siempre al menos 15 dígitos cero adicionales al comienzo.
Y luego se compara la cadena
FileSize
con solo los últimos 16 dígitos con la cadena
0000002147483648
representa 2 GiB en bytes.
strcmp
compara las dos cadenas de igual longitud byte por byte, por lo que cada byte de las dos cadenas comparadas solo puede tener los valores hexadecimales 0x30 a 0x39.
strcmp
regresa inmediatamente con un valor negativo si el byte actual de la cadena izquierda es menor que el byte actual de la cadena derecha, lo que significa que el tamaño del archivo es menor a 2 GiB.
strcmp
regresa inmediatamente con un valor positivo si el byte actual de la cadena izquierda es mayor que el byte actual de la cadena derecha, lo que significa que el tamaño del archivo es mayor que 2 GiB.
strcmp
devuelve con cero en las dos cadenas son 100% idénticas, lo que significa que el tamaño del archivo es exactamente 2 GiB.
Tenga en cuenta que la comparación de valores mediante una comparación de cadenas requiere que ambos valores tengan el mismo número de dígitos para obtener un resultado preciso.
La cadena de valor con menos dígitos debe anteponerse con la cantidad correcta de
0
.
En lote siempre uso
==
cuando uso el comando
if
.
(Por ejemplo:
if "19"=="3" echo My computer doesnt know maths
)
¿Qué pasa con todos los demás (
LSS
,
LEQ
,
NEQ
, etc.)?
¿No hay algo como
!=
Para
NEQ
, o estoy pensando en Unix?
La razón por la que quiero usar símbolos es porque pensé que alguien había dicho que los símbolos de texto o números eran más eficientes que usar las variantes de texto.
De cualquier manera, todavía me gustaría saberlo. Gracias.
La razón por la que no se utilizan operadores como
>
es porque tienen significados especiales en los scripts de shell.
El
>
se usa para redirigir la salida;
<
utilizado para redirigir la entrada, etc.
La documentación de Microsoft enumera los siguientes operadores:
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
Además, la palabra
not
se usa para negar una condición.
La razón por la que quiero usar símbolos es porque pensé que alguien había dicho que los símbolos de texto o números eran más eficientes que usar las variantes de texto.
Probablemente se referían a bash y su gran catálogo de operadores. Proporciona diferentes operadores para operandos enteros y de cadena.