Existe-t-il un moyen d'écrire une instruction conditionnelle IF OU IF dans un fichier batch Windows?
Par exemple:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
Existe-t-il un moyen d'écrire une instruction conditionnelle IF OU IF dans un fichier batch Windows?
Par exemple:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
Réponses:
La solution zmbq est bonne, mais ne peut pas être utilisée dans toutes les situations, comme à l'intérieur d'un bloc de code comme une boucle FOR DO (...).
Une alternative consiste à utiliser une variable indicatrice. Initialisez-le pour qu'il ne soit pas défini, puis définissez-le uniquement si l'une des conditions OR est vraie. Utilisez ensuite IF DEFINED comme test final - pas besoin d'utiliser l'expansion retardée.
FOR ..... DO (
set "TRUE="
IF cond1 set TRUE=1
IF cond2 set TRUE=1
IF defined TRUE (
...
) else (
...
)
)
Vous pouvez ajouter la logique ELSE IF utilisée par arasmussen au motif qu'elle pourrait fonctionner un peu plus vite si la 1ère condition est vraie, mais je ne me dérange jamais.
Addendum - Il s'agit d'une question en double avec des réponses presque identiques à Utilisation d'un OR dans une instruction IF WinXP Batch Script
Addendum final - J'ai presque oublié ma technique préférée pour tester si une variable fait partie d'une liste de valeurs insensibles à la casse. Initialisez une variable de test contenant une liste délimitée de valeurs acceptables, puis utilisez la recherche et le remplacement pour tester si votre variable se trouve dans la liste. C'est très rapide et utilise un code minimal pour une liste arbitrairement longue. Il nécessite une expansion retardée (ou bien l'astuce CALL %% VAR %%). De plus, le test est INSENSIBLE AU CAS.
set "TEST=;val1;val2;val3;val4;val5;"
if "!TEST:;%VAR%;=!" neq "!TEST!" (echo true) else (echo false)
Ce qui précède peut échouer si VAR contient =
, donc le test n'est pas infaillible.
Si vous effectuez le test dans un bloc où une expansion retardée est nécessaire pour accéder à la valeur actuelle de VAR, alors
for ... do (
set "TEST=;val1;val2;val3;val4;val5;"
for /f %%A in (";!VAR!;") do if "!TEST:%%A=!" neq "!TEST!" (echo true) else (echo false)
)
Des options FOR telles que "delims =" peuvent être nécessaires en fonction des valeurs attendues dans VAR
La stratégie ci-dessus peut être rendue fiable même avec =
dans VAR en ajoutant un peu plus de code.
set "TEST=;val1;val2;val3;val4;val5;"
if "!TEST:;%VAR%;=!" neq "!TEST!" if "!TEST:;%VAR%;=;%VAR%;"=="!TEST!" echo true
Mais maintenant, nous avons perdu la capacité de fournir une clause ELSE à moins d'ajouter une variable indicatrice. Le code a commencé à paraître un peu «laid», mais je pense que c'est la méthode la plus performante et fiable pour tester si VAR est l'une des options insensibles à la casse parmi un nombre arbitraire d'options.
Enfin, il existe une version plus simple qui, à mon avis, est légèrement plus lente car elle doit effectuer un IF pour chaque valeur. Aacini a fourni cette solution dans un commentaire à la réponse acceptée dans le lien mentionné ci-dessus
for %%A in ("val1" "val2" "val3" "val4" "val5") do if "%VAR%"==%%A echo true
La liste de valeurs ne peut pas inclure le * ou? caractères et les valeurs et %VAR%
ne doivent pas contenir de guillemets. Les guillemets posent des problèmes si le %VAR%
contient également des espaces ou des caractères spéciaux tels que ^
, &
etc. Une autre limitation de cette solution est qu'elle ne fournit pas l'option pour une clause ELSE sauf si vous ajoutez une variable d'indicateur. Les avantages sont qu'il peut être sensible à la casse ou insensible en fonction de la présence ou de l'absence de l' /I
option IF .
Je ne pense pas. Utilisez simplement deux IF et GOTO la même étiquette:
IF cond1 GOTO foundit
IF cond2 GOTO foundit
ECHO Didn't found it
GOTO end
:foundit
ECHO Found it!
:end
ECHO Didn't find it
même s'il le trouvait.
Merci pour ce post, cela m'a beaucoup aidé.
Je ne sais pas si cela peut aider mais j'ai eu le problème et grâce à vous, j'ai trouvé ce que je pense être un autre moyen de le résoudre basé sur cette équivalence booléenne:
"A ou B" équivaut à "pas (ni A ni B)"
Donc:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
Devient:
IF not [%var%] == [1] IF not [%var%] == [2] ECHO FALSE
Un simple "POUR" peut être utilisé sur une seule ligne pour utiliser une condition "ou":
FOR %%a in (item1 item2 ...) DO IF {condition_involving_%%a} {execute_command}
Appliqué à votre cas:
FOR %%a in (1 2) DO IF %var%==%%a ECHO TRUE
Même si cette question est un peu plus ancienne:
Si vous voulez utiliser if cond1 or cond 2
- vous ne devriez pas utiliser de boucles compliquées ou des trucs comme ça.
Fournissez simplement les deux l'un ifs
après l'autre combinés avec goto
- c'est un ou implicite.
//thats an implicit IF cond1 OR cond2 OR cond3
if cond1 GOTO doit
if cond2 GOTO doit
if cond3 GOTO doit
//thats our else.
GOTO end
:doit
echo "doing it"
:end
Sans goto mais une action "inplace", vous pouvez exécuter l'action 3 fois, si TOUTES les conditions correspondent.
Il n'y a pas de IF <arg> OR
ou ELIF
ou ELSE IF
en lot, cependant ...
Essayez d'imbriquer les autres IF dans l'ELSE du IF précédent.
IF <arg> (
....
) ELSE (
IF <arg> (
......
) ELSE (
IF <arg> (
....
) ELSE (
)
)
Il est possible d'utiliser une fonction qui évalue la logique OU et renvoie une seule valeur.
@echo off
set var1=3
set var2=5
call :logic_or orResult "'%var1%'=='4'" "'%var2%'=='5'"
if %orResult%==1 (
echo At least one expression is true
) ELSE echo All expressions are false
exit /b
:logic_or <resultVar> expression1 [[expr2] ... expr-n]
SETLOCAL
set "logic_or.result=0"
set "logic_or.resultVar=%~1"
:logic_or_loop
if "%~2"=="" goto :logic_or_end
if %~2 set "logic_or.result=1"
SHIFT
goto :logic_or_loop
:logic_or_end
(
ENDLOCAL
set "%logic_or.resultVar%=%logic_or.result%"
exit /b
)
&& ... || ...
syntaxe pratique directement au lieu de l' IF ... ELSE ...
instruction supplémentaire .
L'objectif peut être atteint en utilisant indirectement les FI.
Vous trouverez ci-dessous un exemple d'expression complexe qui peut être écrite de manière assez concise et logique dans un lot CMD, sans étiquettes et GOTO incohérents.
Les blocs de code entre crochets () sont traités par CMD comme une sorte (pathétique) de sous-shell. Quel que soit le code de sortie sortant d'un bloc, il sera utilisé pour déterminer la valeur vrai / faux que le bloc lit dans une expression booléenne plus grande. Des expressions booléennes arbitrairement grandes peuvent être créées avec ces blocs de code.
Exemple simple
Chaque bloc est résolu en vrai (c'est-à-dire ERRORLEVEL = 0 après l'exécution de la dernière instruction du bloc) / faux, jusqu'à ce que la valeur de l'expression entière ait été déterminée ou que le contrôle saute (par exemple via GOTO):
((DIR c:\xsgdde /w) || (DIR c:\ /w)) && (ECHO -=BINGO=-)
Exemple complexe
Cela résout le problème soulevé initialement. Plusieurs instructions sont possibles dans chaque bloc mais dans le || || || expression, il est préférable d'être concis pour qu'il soit aussi lisible que possible. ^ est un caractère d'échappement dans les lots CMD et lorsqu'il est placé à la fin d'une ligne, il échappera à l'EOL et demandera à CMD de continuer à lire le lot actuel d'instructions sur la ligne suivante.
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
(
(CALL :ProcedureType1 a b) ^
|| (CALL :ProcedureType2 sgd) ^
|| (CALL :ProcedureType1 c c)
) ^
&& (
ECHO -=BINGO=-
GOTO :EOF
)
ECHO -=no bingo for you=-
GOTO :EOF
:ProcedureType1
IF "%~1" == "%~2" (EXIT /B 0) ELSE (EXIT /B 1)
GOTO :EOF (this line is decorative as it's never reached)
:ProcedureType2
ECHO :ax:xa:xx:aa:|FINDSTR /I /L /C:":%~1:">nul
GOTO :EOF
If %x%==1 (
If %y%==1 (
:: both are equal to 1.
)
)
C'est pour vérifier si plusieurs variables sont égales à la valeur. Voici pour l'une ou l'autre variable.
If %x%==1 (
:: true
)
If %x%==0 (
If %y%==1 (
:: true
)
)
If %x%==0 (
If %y%==0 (
:: False
)
)
J'ai juste pensé à ça par le haut si ma tête. Je pourrais le compacter davantage.
Je me rends compte que cette question est ancienne, mais je voulais publier une solution alternative au cas où quelqu'un d'autre (comme moi) trouverait ce fil tout en ayant la même question. J'ai pu contourner le manque d'opérateur OR en faisant écho à la variable et en utilisant findstr pour valider.
for /f %%v in ('echo %var% ^| findstr /x /c:"1" /c:"2"') do (
if %errorlevel% equ 0 echo true
)
Bien que la réponse de dbenham soit plutôt bonne, compter sur IF DEFINED
peut vous causer beaucoup de problèmes si la variable que vous vérifiez n'est pas un environnement variable d' . Les variables de script ne bénéficient pas de ce traitement spécial.
Bien que cela puisse sembler être un BS non documenté ridicule, faire une simple requête shell IF
avec IF /?
révèle que,
Le conditionnel DEFINED fonctionne exactement comme EXIST sauf qu'il prend un nom de variable d' environnement et retourne true si la variable d' environnement est définie.
En ce qui concerne la réponse à cette question, y a-t-il une raison de ne pas simplement utiliser un simple drapeau après une série d'évaluations? Cela OR
me semble le contrôle le plus flexible , tant en ce qui concerne la logique sous-jacente que la lisibilité. Par exemple:
Set Evaluated_True=false
IF %condition_1%==true (Set Evaluated_True=true)
IF %some_string%=="desired result" (Set Evaluated_True=true)
IF %set_numerical_variable% EQ %desired_numerical_value% (Set Evaluated_True=true)
IF %Evaluated_True%==true (echo This is where you do your passing logic) ELSE (echo This is where you do your failing logic)
De toute évidence, il peut s'agir de toute sorte d'évaluation conditionnelle, mais je ne partage que quelques exemples.
Si vous vouliez tout avoir sur une seule ligne, écrite, vous pouvez simplement les enchaîner avec &&
comme:
Set Evaluated_True=false
IF %condition_1%==true (Set Evaluated_True=true) && IF %some_string%=="desired result" (Set Evaluated_True=true) && IF %set_numerical_variable% EQ %desired_numerical_value% (Set Evaluated_True=true)
IF %Evaluated_True%==true (echo This is where you do your passing logic) ELSE (echo This is where you do your failing logic)
Je n'ai jamais existé pour travailler.
J'utilise s'il n'existe pas g: xyz / what goto h: Sinon xcopy c: current / files g: bu / current Il y a des modificateurs / a etc. Je ne sais pas lesquels. Ordinateur portable en boutique. Et ordinateur au bureau. Je ne suis pas là.
Jamais fait fonctionner les fichiers batch au-dessus de Windows XP
Une alternative beaucoup plus rapide que j'utilise habituellement est la suivante, comme je peux "ou" un nombre arbitraire de conditions pouvant tenir dans un espace variable
@(
Echo off
Set "_Match= 1 2 3 "
)
Set /a "var=3"
Echo:%_Match%|Find " %var% ">nul || (
REM Code for a false condition goes here
) && (
REM code for a true condition goes here.
)
Réalisant que c'est un peu une vieille question, les réponses m'ont aidé à trouver une solution pour tester les arguments de ligne de commande dans un fichier de commandes; donc je voulais également publier ma solution au cas où quelqu'un d'autre chercherait une solution similaire.
La première chose que je devrais souligner est que j'avais du mal à faire fonctionner les instructions IF ... ELSE à l'intérieur d'une clause FOR ... DO. Il s'avère que (merci à dbenham de l'avoir signalé par inadvertance dans ses exemples) l'instruction ELSE ne peut pas être sur une ligne distincte des parenthèses de fermeture.
Donc au lieu de ça:
FOR ... DO (
IF ... (
)
ELSE (
)
)
Quelle est ma préférence pour la lisibilité et les raisons esthétiques, vous devez faire ceci:
FOR ... DO (
IF ... (
) ELSE (
)
)
Désormais, l'instruction ELSE ne revient pas en tant que commande non reconnue.
Enfin, voici ce que j'essayais de faire - je voulais pouvoir passer plusieurs arguments à un fichier de commandes dans n'importe quel ordre, en ignorant la casse et en signalant / échouant sur des arguments non définis passés. Voici donc ma solution ...
@ECHO OFF
SET ARG1=FALSE
SET ARG2=FALSE
SET ARG3=FALSE
SET ARG4=FALSE
SET ARGS=(arg1 Arg1 ARG1 arg2 Arg2 ARG2 arg3 Arg3 ARG3)
SET ARG=
FOR %%A IN (%*) DO (
SET TRUE=
FOR %%B in %ARGS% DO (
IF [%%A] == [%%B] SET TRUE=1
)
IF DEFINED TRUE (
SET %%A=TRUE
) ELSE (
SET ARG=%%A
GOTO UNDEFINED
)
)
ECHO %ARG1%
ECHO %ARG2%
ECHO %ARG3%
ECHO %ARG4%
GOTO END
:UNDEFINED
ECHO "%ARG%" is not an acceptable argument.
GOTO END
:END
Notez que cela ne rapportera que le premier argument ayant échoué. Donc, si l'utilisateur passe plus d'un argument inacceptable, il ne sera informé du premier que jusqu'à ce qu'il soit corrigé, puis du second, etc.
IF [%var%]==[1] IF [%var2%]==[2] ECHO BOTH ARE TRUE
. Je l' habitude de définirSET AND=IF
et écrire:IF cond1 %AND% cond2 ECHO BOTH ARE TRUE
.