Opérateurs logiques («et», «ou») en lot DOS

Réponses:

289

Vous pouvez faire andavec des conditions imbriquées:

if %age% geq 2 (
    if %age% leq 12 (
        set class=child
    )
)

ou:

if %age% geq 2 if %age% leq 12 set class=child

Vous pouvez le faire oravec une variable distincte:

set res=F
if %hour% leq 6 set res=T
if %hour% geq 22 set res=T
if "%res%"=="T" (
    set state=asleep
)
paxdiablo
la source
14
Vous pouvez également simplement utiliser set res=ou set res=1et puis if defined resqui est un peu plus robuste contre les fautes de frappe et fonctionne même dans les blocs sans activer explicitement l'expansion retardée.
Joey
5
Juste pour améliorer un peu votre réponse ... vous n'avez pas besoin d'imbriquer explicitement les instructions "si" ... vous pouvez simplement les "enchaîner", comme le démontre Dave Jarvis ci
JoelFan
Attention à ne laisser aucun espace après le set = true ou la chose ne fonctionne pas gracieusement. Il stockerait la valeur "true" dans la variable ...
Roland Pihlakas
1
La condition «ou» que vous décrivez est lisse et fonctionne très bien pour une plage de nombres, mais que se passe-t-il si je compare 2 valeurs indépendantes, et non une plage? Par exemple, si ce fichier existe ou nom de fichier == ""
bakoyaro
1
@bakoyaro, vous pouvez utiliser n'importe quelle condition pour définir res sur true, y compris celles que vous mentionnez.
paxdiablo
69

L' IFinstruction ne prend pas en charge les opérateurs logiques ( ANDet OR), les IFinstructions en cascade font une conjonction implicite.

IF Exist File1.Dat IF Exist File2.Dat GOTO FILE12_EXIST_LABEL

Si File1.Dat et File1.Dat existent, sautez l'étiquette FILE12_EXIST_LABEL.

Voir également: IF /?

Dave Jarvis
la source
53

Les lois de De Morgan nous permettent de convertir les disjonctions ("OU") en équivalents logiques en utilisant uniquement les conjonctions ("ET") et les négations ("NON"). Cela signifie que nous pouvons enchaîner les disjonctions ("OU") sur une seule ligne.

Cela signifie que si le nom est "Yakko" ou "Wakko" ou "Dot", alors faites écho à "frère ou sœur Warner".

set warner=true
if not "%name%"=="Yakko" if not "%name%"=="Wakko" if not "%name%"=="Dot" set warner=false
if "%warner%"=="true" echo Warner brother or sister

Il s'agit d'une autre version de l'exemple "OR" de paxdiablo, mais les conditions sont enchaînées sur une seule ligne. (Notez que l'opposé de leqest gtret l'opposé de geqest lss.)

set res=true
if %hour% gtr 6 if %hour% lss 22 set res=false
if "%res%"=="true" set state=asleep
anomalie
la source
6

Les exemples suivants montrent comment créer une instruction AND (utilisée pour définir des variables ou inclure des paramètres pour une commande).

Pour démarrer le Bloc-notes et fermer la fenêtre CMD:

start notepad.exe & exit

Pour définir les variables x, y et z sur des valeurs si la variable «a» est égale à bla.

IF "%a%"=="blah" (set x=1) & (set y=2) & (set z=3)

J'espère que cela pourra aider!

GinDiamond
la source
5

OU est un peu délicat, mais pas trop. Voici un exemple

set var1=%~1
set var2=%~2
::
set or_=
if "%var1%"=="Stack" set or_=true
if "%var2%"=="Overflow" set or_=true
if defined or_ echo Stack OR Overflow
Timo Salmi
la source
2

Athul Prakash (16 ans à l'époque) a donné une idée logique de la façon d'implémenter un test OR en annulant les conditions dans les instructions IF, puis en utilisant la clause ELSE comme emplacement pour placer le code qui doit être exécuté. Je me suis dit qu'il y avait cependant deux autres clauses généralement nécessaires car il suggère d'utiliser deux instructions IF, et donc le code exécuté doit être écrit deux fois . Cependant, si un GOTO est utilisé pour ignorer le code requis, au lieu d'écrire des clauses ELSE, le code d'exécution ne doit être écrit qu'une seule fois .

Voici un exemple testable de la façon dont j'implémenterais la logique négative d'Athul Prakash pour créer un OU .

Dans mon exemple, quelqu'un est autorisé à conduire un char s'il a un permis de char OU s'il fait son service militaire . Entrez vrai ou faux aux deux invites et vous pourrez voir si la logique vous permet de conduire un char.

@ECHO OFF
@SET /p tanklicence=tanklicence:
@SET /p militaryservice=militaryservice:

IF /I NOT %tanklicence%==true IF /I NOT %militaryservice%==true GOTO done

ECHO I am driving a tank with tanklicence set to %tanklicence% and militaryservice set to %militaryservice%

:done

PAUSE
Ivan
la source
2

Si vous êtes intéressé à écrire un if+ AND/ ORdans une déclaration, alors il n'y en a pas. Mais, vous pouvez toujours grouper ifavec les instructions &&/ ||et (/ )pour obtenir ce que vous voulez sur une seule ligne sans aucune variable supplémentaire et sans if-elseduplication de bloc ( echocommande unique pour les sections de code TRUEet FALSE):

@echo off

setlocal

set "A=1" & set "B=2" & call :IF_AND
set "A=1" & set "B=3" & call :IF_AND
set "A=2" & set "B=2" & call :IF_AND
set "A=2" & set "B=3" & call :IF_AND

echo.

set "A=1" & set "B=2" & call :IF_OR
set "A=1" & set "B=3" & call :IF_OR
set "A=2" & set "B=2" & call :IF_OR
set "A=2" & set "B=3" & call :IF_OR

exit /b 0

:IF_OR
( ( if %A% EQU 1 ( type nul>nul ) else type 2>nul ) || ( if %B% EQU 2 ( type nul>nul ) else type 2>nul ) || ( echo.FALSE-& type 2>nul ) ) && echo TRUE+

exit /b 0

:IF_AND
( ( if %A% EQU 1 ( type nul>nul ) else type 2>nul ) && ( if %B% EQU 2 ( type nul>nul ) else type 2>nul ) && echo.TRUE+ ) || echo.FALSE-


exit /b 0

Sortie :

TRUE+
FALSE-
FALSE-
FALSE-

TRUE+
TRUE+
TRUE+
FALSE-

L'astuce réside dans la typecommande qui supprime / définit le errorlevelet gère ainsi le chemin vers la commande suivante.

Andry
la source
1

Essayez l'opérande de négation - «non»!

Eh bien, si vous pouvez effectuer une opération «ET» sur une instruction if à l'aide de «si» imbriqués (reportez-vous aux réponses précédentes), vous pouvez faire la même chose avec «sinon» pour effectuer une opération «ou».

Si vous n'avez pas encore l'idée, lisez la suite. Sinon, ne perdez pas votre temps et revenez à la programmation.

Tout comme les «si» imbriqués ne sont satisfaits que lorsque toutes les conditions sont vraies, les «si non imbriqués» ne sont satisfaits que lorsque toutes les conditions sont fausses. C'est similaire à ce que vous voulez faire avec un opérande 'ou', n'est-ce pas?

Même lorsque l'une des conditions du «sinon» imbriqué est vraie, l'énoncé dans son ensemble n'est pas satisfait. Par conséquent, vous pouvez utiliser successivement les «si négatifs» en vous rappelant que le corps de l'énoncé de condition doit être ce que vous voulez faire si toutes vos conditions imbriquées sont fausses. Le corps que vous vouliez réellement donner devrait relever de la déclaration else.

Et si vous n'avez toujours pas compris l'essentiel de la chose, désolé, j'ai 16 ans et c'est le mieux que je puisse faire pour expliquer.

Athul Prakash
la source
x = 2 ou x = 3 =>! ! (x = 2 ou x = 3) =>! (x! = 2 et x! = 3) Je ne pense pas que vous puissiez annuler la structure entière if pour appliquer l'opérateur "not" externe nécessaire. Cela fait 3 ans, @ Athul-prakash, pensées?
Azeroth2b
1

C'est aussi simple que ce qui suit:

ET> si + si

if "%VAR1%"=="VALUE" if "%VAR2%"=="VALUE" *do something*

OU> si // si

set BOTH=0
if "%VAR1%"=="VALUE" if "%VAR2%"=="VALUE" set BOTH=1
if "%BOTH%"=="0" if "%VAR1%"=="VALUE" *do something*
if "%BOTH%"=="0" if "%VAR2%"=="VALUE" *do something*

Je sais qu'il y a d'autres réponses, mais je pense que la mienne est plus simple, donc plus facile à comprendre. J'espère que cela vous aide! ;)

Logiciel Renk
la source
0

Une alternative est de chercher un shell Unix qui vous donne des opérateurs logiques et bien plus encore. Vous pouvez obtenir une implémentation native Win32 d'un shell Bourne ici si vous ne voulez pas emprunter la route cygwin. Un bash natif peut être trouvé ici . Je suis certain que vous pouvez facilement rechercher sur Google d'autres bonnes alternatives telles que zsh ou tcsh.

K

Kevin Shea
la source
4
Si vous allez faire l'effort d'utiliser un autre shell, allez au moins avec PowerShell: microsoft.com/powershell
Eclipse
17
Il existe de bien meilleurs shells que DOS. La raison pour laquelle j'utiliserais un fichier de batte DOS est qu'il ne nécessite aucun outil externe. Si vous avez un client qui a besoin d'automatiser quelque chose de simple, voulez-vous vraiment qu'il doive installer des outils spéciaux (cygwin, perl, powershell, etc.) quand un fichier BAT suffira?
Mark Lakata
3
La MTD est suffisante la plupart du temps. 90% des scripts shell unix écrits par ppl ne sont pas du shell pur mais avec de nombreux appels coreutils, sed, awk etc. GNU a implémenté des goodies UNIX dans d'autres OS, y compris Windows. Jetez donc un œil à ce getgnuwin32.sourceforge.net cmd.exe / bash / zsh et cela devrait être suffisant pour la plupart des tâches. Aucune raison d'apprendre le soi-disant PowerShell si vous avez une expérience Shell BAT / UNIX
MeaCulpa
0

Seule la partie OU est délicate, mais avec une expression booléenne générale contenant PAS OU ET la seule bonne solution est la suivante:

REM if A == B OR C == C then yes

(call :strequ A B || call :strequ C C) && echo yes
exit /b

:strequ
if "%1" == "%2" exit /b 0
exit /b 1
Henrik4
la source
-1

Légère modification de la réponse d'Andry, réduisant les commandes de type en double:

set "A=1" & set "B=2" & call :IF_AND
set "A=1" & set "B=3" & call :IF_AND
set "A=2" & set "B=2" & call :IF_AND
set "A=2" & set "B=3" & call :IF_AND

echo.

set "A=1" & set "B=2" & call :IF_OR
set "A=1" & set "B=3" & call :IF_OR
set "A=2" & set "B=2" & call :IF_OR
set "A=2" & set "B=3" & call :IF_OR

goto :eof

:IF_OR

(if /i not %A% EQU 1 (
   if /i not %B% EQU 2 (
      echo FALSE-
      type 2>nul
   )
)) && echo TRUE+

goto :eof

:IF_AND


(if /i %A% EQU 1 (
   if /i %B% EQU 2 (
      echo TRUE+
      type 2>nul
   )
)) && echo FALSE-

goto :eof
TedK
la source