¿Hay alguna manera de escribir una declaración condicional IF O IF en un archivo por lotes de Windows?
Por ejemplo:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
windows
batch-file
if-statement
cmd
conditional
Mechaflash
fuente
fuente
IF [%var%]==[1] IF [%var2%]==[2] ECHO BOTH ARE TRUE
. He utilizado para definirSET AND=IF
y luego escribir:IF cond1 %AND% cond2 ECHO BOTH ARE TRUE
.Respuestas:
La solución zmbq es buena, pero no se puede usar en todas las situaciones, como dentro de un bloque de código como un bucle FOR DO (...).
Una alternativa es utilizar una variable indicadora. Inicialícelo para que no esté definido y, a continuación, defínalo solo si alguna de las condiciones OR es verdadera. Luego use SI SE DEFINE como prueba final - no es necesario usar expansión retardada.
Podría agregar la lógica ELSE IF que utiliza arasmussen con el argumento de que podría funcionar un poco más rápido si la primera condición es verdadera, pero nunca me molesto.
Anexo : esta es una pregunta duplicada con respuestas casi idénticas a Usar un OR en una instrucción IF WinXP Batch Script
Apéndice final : casi olvido mi técnica favorita para probar si una variable es cualquiera de una lista de valores que no distinguen entre mayúsculas y minúsculas. Inicialice una variable de prueba que contenga una lista delimitada de valores aceptables, y luego use buscar y reemplazar para probar si su variable está dentro de la lista. Esto es muy rápido y utiliza un código mínimo para una lista arbitrariamente larga. Requiere expansión retardada (o el truco CALL %% VAR %%). Además, la prueba es INSENSIBLE AL CASO.
Lo anterior puede fallar si VAR lo contiene
=
, por lo que la prueba no es infalible.Si realiza la prueba dentro de un bloque donde se necesita expansión retardada para acceder al valor actual de VAR, entonces
FOR opciones como "delims =" pueden ser necesarias según los valores esperados dentro de VAR
La estrategia anterior se puede hacer confiable incluso con
=
VAR agregando un poco más de código.Pero ahora hemos perdido la capacidad de proporcionar una cláusula ELSE a menos que agreguemos una variable indicadora. El código ha comenzado a verse un poco "feo", pero creo que es el método confiable de mejor desempeño para probar si VAR es cualquiera de un número arbitrario de opciones que no distinguen entre mayúsculas y minúsculas.
Finalmente, hay una versión más simple que creo que es un poco más lenta porque debe realizar un SI para cada valor. Aacini proporcionó esta solución en un comentario a la respuesta aceptada en el enlace antes mencionado
La lista de valores no puede incluir * o? caracteres y los valores y
%VAR%
no deben contener comillas. Las comillas dan lugar a problemas si%VAR%
también contienen espacios o caracteres especiales como^
,&
etc. Otra limitación de esta solución es que no proporciona la opción para una cláusula ELSE a menos que agregue una variable indicadora. Las ventajas son que puede distinguir entre mayúsculas y minúsculas o no, según la presencia o ausencia de la/I
opción IF .fuente
No lo creo. Simplemente use dos IF y GOTO la misma etiqueta:
fuente
ECHO Didn't find it
incluso si lo encontrara.Gracias por esta publicación, me ayudó mucho.
No sé si puede ayudar, pero tuve el problema y gracias a ti encontré lo que creo que es otra forma de resolverlo en función de esta equivalencia booleana:
"A o B" es lo mismo que "no (ni A ni B)"
Así:
Se convierte en:
fuente
Se puede usar un simple "FOR" en una sola línea para usar una condición "o":
Aplicado a su caso:
fuente
Incluso si esta pregunta es un poco más antigua:
Si desea usar
if cond1 or cond 2
, no debe usar bucles complicados o cosas así.Proporcione ambos simples uno
ifs
después del otro combinado congoto
- eso es un implícito o.Sin goto pero una acción "in situ", puede ejecutar la acción 3 veces, si TODAS las condiciones coinciden.
fuente
Sin embargo, no hay
IF <arg> OR
oELIF
oELSE IF
en Lote ...Intente anidar los otros IF dentro del ELSE del IF anterior.
fuente
Es posible utilizar una función, que evalúa la lógica OR y devuelve un solo valor.
fuente
&& ... || ...
sintaxis conveniente directamente en lugar de laIF ... ELSE ...
declaración adicional .El objetivo se puede lograr utilizando IF indirectamente.
A continuación se muestra un ejemplo de una expresión compleja que se puede escribir de manera bastante concisa y lógica en un lote de CMD, sin etiquetas incoherentes ni GOTO.
CMD maneja los bloques de código entre corchetes () como un tipo (patético) de subcapa. Cualquier código de salida que salga de un bloque se utilizará para determinar el valor verdadero / falso que el bloque reproduce en una expresión booleana más grande. Se pueden construir expresiones booleanas arbitrariamente grandes con estos bloques de código.
Ejemplo simple
Cada bloque se resuelve en verdadero (es decir, ERRORLEVEL = 0 después de que se haya ejecutado la última declaración del bloque) / falso, hasta que se haya determinado el valor de toda la expresión o el control salte (por ejemplo, a través de GOTO):
Ejemplo complejo
Esto resuelve el problema planteado inicialmente. Son posibles varias declaraciones en cada bloque pero en el || || || expresión es preferible ser conciso para que sea lo más legible posible. ^ es un carácter de escape en lotes de CMD y cuando se coloca al final de una línea escapará del EOL e indicará a CMD que continúe leyendo el lote actual de declaraciones en la siguiente línea.
fuente
Eso es para verificar si varias variables tienen el mismo valor. Aquí está para cualquiera de las variables.
Solo pensé en eso de la parte superior de mi cabeza. Podría compactarlo más.
fuente
Me doy cuenta de que esta pregunta es antigua, pero quería publicar una solución alternativa en caso de que alguien más (como yo) encontrara este hilo mientras tenía la misma pregunta. Pude solucionar la falta de un operador OR haciendo eco de la variable y usando findtr para validar.
fuente
Si bien la respuesta de dbenham es bastante buena, confiar en ella
IF DEFINED
puede causarle muchos problemas si la variable que está verificando no es una variable de entorno . Las variables de script no reciben este tratamiento especial.Si bien esto puede parecer una tontería ridícula e indocumentada, hacer una simple consulta de shell de
IF
withIF /?
revela que,Con respecto a responder a esta pregunta, ¿hay alguna razón para no usar simplemente una bandera después de una serie de evaluaciones? Eso me parece el
OR
control más flexible , tanto en lo que respecta a la lógica subyacente como a la legibilidad. Por ejemplo:Obviamente, pueden ser cualquier tipo de evaluación condicional, pero solo estoy compartiendo algunos ejemplos.
Si quisiera tenerlo todo en una línea, por escrito, podría simplemente encadenarlos con
&&
like:fuente
Nunca llegué a existir para trabajar.
Yo uso si no existe g: xyz / what goto h: Else xcopy c: current / files g: bu / current Hay modificadores / a, etc. No estoy seguro de cuáles. Laptop en tienda. Y computadora en la oficina. No estoy ahí.
Nunca conseguí que los archivos por lotes funcionaran por encima de Windows XP
fuente
Una alternativa mucho más rápida que suelo usar es la siguiente, ya que puedo "o" un número arbitrario de condiciones que pueden caber en un espacio variable
fuente
Al darme cuenta de que esta es una pregunta un poco vieja, las respuestas me ayudaron a encontrar una solución para probar los argumentos de la línea de comandos en un archivo por lotes; así que también quería publicar mi solución en caso de que alguien más estuviera buscando una solución similar.
Lo primero que debo señalar es que estaba teniendo problemas para que las declaraciones IF ... ELSE funcionen dentro de una cláusula FOR ... DO. Resulta que (gracias a dbenham por señalar esto inadvertidamente en sus ejemplos) la declaración ELSE no puede estar en una línea separada de los parens de cierre.
Entonces en lugar de esto:
Que es mi preferencia por motivos de legibilidad y estética, tienes que hacer esto:
Ahora la instrucción ELSE no regresa como un comando no reconocido.
Finalmente, esto es lo que estaba tratando de hacer: quería poder pasar varios argumentos a un archivo por lotes en cualquier orden, ignorando el caso e informando / fallando sobre argumentos indefinidos pasados. Así que aquí está mi solución ...
Tenga en cuenta que esto solo informará sobre el primer argumento fallido. Entonces, si el usuario pasa más de un argumento inaceptable, solo se le informará sobre el primero hasta que se corrija, luego el segundo, etc.
fuente