windows batch-file if-statement cmd

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:

  1. == que ejecuta una comparación de cadenas de los dos argumentos sobre igualdad, es decir, usa strcmp con la condición verdadera en strcmp devuelve 0.
  2. 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.