Operatori logici ("e", "o") nel batch DOS


Risposte:


289

Puoi fare andcon le condizioni nidificate:

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

o:

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

Puoi fare orcon una variabile separata:

set res=F
if %hour% leq 6 set res=T
if %hour% geq 22 set res=T
if "%res%"=="T" (
    set state=asleep
)

14
Puoi anche semplicemente usare set res=o set res=1e quindi if defined resche è un po 'più robusto contro i refusi e funziona anche in blocchi senza consentire esplicitamente l'espansione ritardata.
Joey,

5
Solo per migliorare un po 'la tua risposta ... non è necessario nidificare esplicitamente le dichiarazioni "if" ... puoi semplicemente "incatenarle", come dimostra Dave Jarvis di seguito
JoelFan,

Fai attenzione a non lasciare spazi dopo il set = true o la cosa semplicemente non funziona con garbo. Memorizzerebbe il valore "vero" nella variabile ...
Roland Pihlakas,

1
La condizione 'o' che descrivi è liscia e funziona benissimo per un intervallo di numeri, ma cosa succede se sto confrontando 2 valori indipendenti e non un intervallo? Ad esempio, se questo file esiste o il nome file == ""
bakoyaro,

1
@bakoyaro, puoi utilizzare qualsiasi condizione per impostare res su true, comprese quelle che menzioni.
paxdiablo,

69

L' IFistruzione non supporta gli operatori logici ( ANDe OR), le IFistruzioni a cascata formano una congiunzione implicita.

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

Se File1.Dat ed File1.Dat esiste, quindi saltare l'etichettaFILE12_EXIST_LABEL .

Guarda anche: IF /?


53

Le leggi di De Morgan ci consentono di convertire le disgiunzioni ("OR") in equivalenti logici usando solo congiunzioni ("AND") e negazioni ("NOT"). Ciò significa che possiamo concatenare disgiunzioni ("OR") su una riga.

Questo significa che se il nome è "Yakko" o "Wakko" o "Dot", allora fai eco a "Warner fratello o sorella".

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

Questa è un'altra versione dell'esempio "OR" di paxdiablo, ma le condizioni sono concatenate su una riga. (Nota che l'opposto di leqè gtre l'opposto di geqè lss.)

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

6

Gli esempi seguenti mostrano come creare un'istruzione AND (utilizzata per impostare variabili o includere parametri per un comando).

Per avviare Blocco note e chiudere la finestra CMD:

start notepad.exe & exit

Per impostare le variabili x, ye z su valori se la variabile 'a' è uguale a blah.

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

Spero che aiuti!


5

O è leggermente complicato, ma non eccessivamente. Ecco un esempio

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

2

Athul Prakash (16 anni all'epoca) ha dato un'idea logica di come implementare un test OR negando le condizioni nelle istruzioni IF e quindi usando la clausola ELSE come posizione per inserire il codice che richiede l'esecuzione. Ho pensato a me stesso che ci sono comunque altre due clausole di solito necessarie poiché sta suggerendo di usare due istruzioni IF, e quindi il codice eseguito deve essere scritto due volte . Tuttavia, se si utilizza un GOTO per saltare il codice richiesto, invece di scrivere clausole ELSE, il codice per l'esecuzione deve essere scritto solo una volta .

Ecco un esempio verificabile di come implementerei la logica negativa di Athul Prakash per creare un OR .

Nel mio esempio, a qualcuno è permesso guidare un carro armato se hanno una licenza di carro armato O stanno facendo il loro servizio militare . Inserisci vero o falso ai due messaggi e sarai in grado di vedere se la logica ti consente di guidare un carro armato.

@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

2

Se sei interessato a scrivere un if+ AND/ ORin un'istruzione, non ce n'è nessuna. Tuttavia, è ancora possibile raggruppare ifcon &&/ ||e (/ )istruzioni per ottenere ciò che si desidera in una riga senza variabili aggiuntive e senza if-elseduplicazione del blocco ( echocomando singolo per TRUEe FALSEsezioni di codice):

@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

Uscita :

TRUE+
FALSE-
FALSE-
FALSE-

TRUE+
TRUE+
TRUE+
FALSE-

Il trucco sta nel typecomando che rilascia / imposta il errorlevele quindi gestisce la strada per il comando successivo.


1

Prova l'operando di negazione - "no"!

Bene, se puoi eseguire un'operazione 'AND' su un'istruzione if usando if nidificati (fai riferimento alle risposte precedenti), allora puoi fare la stessa cosa con 'if not' per eseguire un'operazione 'o'.

Se non hai ancora avuto l'idea, continua a leggere. Altrimenti, non perdere tempo e torna alla programmazione.

Proprio come se i nidificati fossero soddisfatti solo quando tutte le condizioni sono vere, i nidificati se non fossero soddisfatti solo quando tutte le condizioni fossero false. È simile a quello che vuoi fare con un operando 'o', non è vero?

Anche quando una delle condizioni nel nidificato "se non" è vera, l'intera affermazione rimane non soddisfatta. Quindi, puoi usare "if's in successione negato" ricordando che il corpo dell'istruzione condition dovrebbe essere quello che vuoi fare se tutte le tue condizioni nidificate sono false. Il corpo che in realtà volevi dare dovrebbe rientrare nell'affermazione else.

E se non hai ancora capito bene, mi dispiace, ho 16 anni ed è il massimo che posso fare per spiegare.


x = 2 o x = 3 =>! ! (x = 2 o x = 3) =>! (x! = 2 and x! = 3) Non credo che tu possa negare il tutto se la struttura dovesse applicare l'operatore "non" esterno necessario. Sono passati 3 anni, @ Athul-Prakash, pensieri?
Azeroth2b

1

È semplice quanto il seguente:

AND> if + if

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

OPPURE> if // if

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*

So che ci sono altre risposte, ma penso che la mia sia più semplice, quindi più facile da capire. Spero che questo ti aiuti! ;)


0

Un'alternativa è cercare una shell unix che ti dia operatori logici e molto altro. È possibile ottenere un'implementazione nativa win32 di una shell Bourne qui se non si desidera seguire la rotta Cygwin. Un bash nativo può essere trovato qui . Sono abbastanza sicuro che potresti facilmente google altre buone alternative come zsh o tcsh.

K


4
Se hai intenzione di passare attraverso lo sforzo di utilizzare una shell diversa, almeno vai con PowerShell: microsoft.com/powershell
Eclipse

17
Ci sono molte shell migliori rispetto a DOS. Il motivo per cui vorrei usare un file bat DOS è perché non richiede strumenti esterni. Se hai un cliente che deve automatizzare qualcosa di semplice, vuoi davvero che debbano installare strumenti speciali (cygwin, perl, powershell, ecc.) Quando sarà sufficiente un file BAT?
Mark Lakata,

3
La BAT è abbastanza per la maggior parte del tempo. Il 90% degli script shell unix ppl write non è pura shell ma con molte chiamate coreutils, sed, awk ecc. GNU ha implementato goodies UNIX in altri sistemi operativi, incluso Windows. Quindi dai un'occhiata a questo cmgn.exe / bash / zsh getgnuwin32.sourceforge.net e questo dovrebbe essere sufficiente per la maggior parte delle attività. Nessun motivo per apprendere il cosiddetto PowerShell se hai esperienza con la shell BAT / UNIX
MeaCulpa,

0

Solo la parte OR è complicata, ma con un'espressione booleana generale contenente NOT OR AND l'unica soluzione piacevole è questa:

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

-1

Leggera modifica alla risposta di Andry, riducendo i comandi di tipo duplicato:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.