2010-05-05 18 views
13

in file batch DOS, in una dichiarazione IF, è possibile combinare due o più condizioni utilizzando AND o OR? Non ero in grado di trovare alcuna documentazione per quellacmd.exe: condizioni complesse?

Modifica-help if e la documentazione MS non dire nulla su come utilizzare più di una condizione in un caso.

immagino una soluzione per e sarebbe fare

if COND1 (
    if COND2 (
    cmd 
) 
) 

ma questo è esattamente quello che sto cercando di evitare.

+1

Quando hai digitato 'HELP IF' cosa hai visto? Qualcosa di utile? Leggi 'HELP IF' e poi aggiorna la tua domanda per essere più specifica in base a ciò che leggi. –

+0

Inoltre, stai chiedendo questa pagina della documentazione Microsoft? http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/batch.mspx?mfr=true –

risposta

14

No, non esiste un modo più semplice.

Per and si può anche semplicemente catena senza blocchi che introducono:

if COND1 if COND2 ... 

che francamente non è peggio di

if COND1 and COND2 ... 

Tuttavia, per or diventa più brutta, anzi:

set COND= 
if COND1 set COND=1 
if COND2 set COND=1 
if defined COND ... 

oppure:

if COND1 goto :meh 
if COND2 goto :meh 
goto :meh2 
:meh 
... 
:meh2 

Una volta ho visto un preprocessore batch che utilizzava la sintassi di tipo C per il flusso di controllo e le partite in batch e quindi convertiva tali condizionali in più salti e controlli. Tuttavia, quella cosa era per i file batch DOS ed era di poca o nessuna utilità in un ambiente Windows.

+0

Buono ... se il set di condizioni è più breve, è possibile combinarle in uno, come: se COND1 ha impostato COND = 1 else se COND1 ha impostato COND = 1 – Arun

+0

Sì, ma questo aiuta solo per le condizioni con AND. – Joey

-6

Finché le estensioni dei comandi sono abilitate, è possibile utilizzare gli operatori di confronto.

questo è direttamente incollato da "aiuto se":

Se le estensioni ai comandi sono abilitate IF cambia come segue:

IF [/I] string1 compare-op string2 command 
IF CMDEXTVERSION number command 
IF DEFINED variable command 

dove confrontare-op può essere uno dei seguenti:

EQU - equal 
NEQ - not equal 
LSS - less than 
LEQ - less than or equal 
GTR - greater than 
GEQ - greater than or equal 

e l'opzione/I, se specificato, dice di eseguire la stringa senza distinzione tra maiuscole e minuscole confronti. L'opzione/I può anche essere utilizzata sul formato stringa1 == stringa2 di IF. Questi confronti sono generici, in quanto se sia string1 che stringa2 sono entrambi composti da tutte le cifre numeriche, le stringhe sono convertite in numeri e viene eseguito un confronto numerico.

+2

Quindi, dov'è il logico 'and' e' or' chiesto l'OP? La domanda non riguardava semplici condizioni di confronto. – Joey

+0

@Johannes Rössel: doh, mi dispiace, mio ​​male. Ho bisogno di leggere più attentamente. – Vicky

+0

-1 - solo un altro e si può ottenere un badge Peer Pressure ;-) – SamB

2

Per il workaround AND sono d'accordo con Joey, non riesco a vedere un'altra soluzione.

Per la soluzione O proporrei la seguente 'trucco':
Diciamo che si desidera verificare se l'utente ha chiesto aiuto sulla riga di comando durante la chiamata per il file batch, qualcosa come: thebatch /?.
Ma non si sa se l'utente digiterà /? o meglio (essendo un utente abituato a Unix) --help o -h o addirittura dimenticarsi di passare qualsiasi argomento.

Il codice potrebbe essere come:

for %%P in ("" "-h" "--help") do if "%1"==%%P (
    :help 
    echo this is my help... >&2 
    exit /b 9 
) 

Nota tuttavia che il test "? /" o "-?" le stringhe non funzionano con quel trucco (i loop FOR non amano il meta carattere ?).
A tal fine, è sufficiente aggiungere la linea: if "%1"=="/?" goto help sulla parte superiore del blocco (vedere l'etichetta di ':help'all'interno delforciclo?)

Nota anche che questa sintassi non funziona (è solo completamente ignorato e il codice non verrà eseguito) con i file batch in TCC.EXE (l'interprete Take Command, completo o lite), ma in tal caso basta usare la loro sintassi con le loro parole chiave .OR. e .AND..

Spero che questo aiuti.

9

A volte mi chiedo, cosa le persone imparano a scuola oggigiorno! Ovviamente anche 'OR' è possibile. Qualsiasi sistema in grado di fornire un 'NOT' e un 'AND', fornisce automaticamente anche un 'OR', perché:

x O y = NOT ((NON x) E (NON y)) vedere http://en.wikipedia.org/wiki/De_Morgan%27s_laws

quindi, fintanto che l'espressione "se (x e Y) poi fare z" possono essere scritte in questo modo:

if (x) if (y) (do z) 

... dovremmo essere in grado di scrivere l'espressione "se (x Oy), quindi fare z ", ma c'è un problema:

Dove mettere il primo 'NOT'? Bene, la risposta è da nessuna parte, dobbiamo riformare l'equazione precedente primo a:

NON (X o Y) = (NOT x) AND (NOT y)

In base a questo, possiamo scrivere " if (NOT (x o Y)) allora (fare z)" come:

"if ((NON x) e (NON y)) allora (fare z)"

Avendo questo e saper express E come mostrato sopra, ora possiamo scrivere l'espressione "if (NOT (x OR y)) then (do z)" come:

if (not x) if (not y) (REM do z) 

Sappiamo anche che l'espressione:

"se (non p) allora (fare q) altro (do r)"

...è equivalente a:

"if (p) allora (fare r) altro (do q)

Quindi possiamo scrivere per "if (x O y) allora (fare z)":

"se (NOT (x o Y)) allora (non fare nulla) altro (fare z)"

Così possiamo esprimere "se (x o Y) allora (fare z)" come:

if (not x) if (not y) (REM do nothing) else (REM do z) 

Ma questo non è ancora completo, perché questo non è un vero "AND" ma un "simulato". Quello che manca è il secondo altro. Quindi il modulo completo per ottenere il risultato corretto dovrebbe essere:

if (not x) (if (not y) (REM do nothing) else (REM do z)) else (REM do z)) 

... che ha la brutta seconda parte. È possibile risolvere che con un 'goto' e noi finalmente avere:

rem if (x OR y) then (do z): 
if (not x) (if (not y) (goto :doNothing)) 
rem do z 
:doNothing 
+0

Sembra avvincente, ma funziona. Grazie! –

0

Se le condizioni stanno controllando per i valori specifici di una variabile, si potrebbe essere in grado di configurarlo come una dichiarazione CASE. Ho avuto bisogno di verificare se il TYPE fosse un singolo membro o un gruppo (o tutti).

Nota: le etichette non fanno distinzione tra maiuscole e minuscole.

Se una delle condizioni sono vere (se TYPE==ALL o TYPE==GROUP1 o TYPE==GROUP2), allora il blocco di codice esegue, altrimenti salta esecuzione sul blocco.

goto :TYPE_EQ_%TYPE% 2>NUL 
if %ERRORLEVEL% neq 0 goto :END_CASE_TYPE 
:TYPE_EQ_ALL 
:TYPE_EQ_GROUP1 
:TYPE_EQ_GROUP2 
rem do what you need 
    echo GROUP: %TYPE% 
:END_CASE_TYPE 

che non mi piace di Mehrdad Ingegneria Elettrica (elettronica digitale) approccio. Sebbene accurato, con l'ingegneria del software, l'idea, come indicato dall'OP, è rendere le cose più semplici da capire. Le istruzioni nidificate if aggiungono Complessità (McCabe). L'aggiunta di NOT in più non aiuta.

La mia soluzione è un po 'strana se non si conosce l'impostazione goto-label/errore, ma si tratta di una struttura piatta che è impostata approssimativamente come un'istruzione if con diverse condizioni OR che non sono difficile da decifrare.

0

E:

IF <COND1> IF <COND2> ACTION 

O:

(SET _=) & (IF <COND1> (SET _=) ELSE IF <COND2> (SET _=)) & IF DEFINED _ ACTION 

Per attuare O in questo modo, si ha bisogno estensioni ai comandi.