DOS toplu işindeki mantıksal işleçler (“ve”, “veya”)


Yanıtlar:


289

Sen yapabilirsin andiç içe koşullarla:

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

veya:

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

Sen yapabilirsin orayrı değişkenle:

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

14
Ayrıca , yazım hatalarına karşı biraz daha sağlam olan ve sonra da gecikmeli genişlemeyi etkinleştirmeden bloklarda bile çalışan daha fazla set res=veya set res=1daha sonra kullanabilirsiniz if defined res.
Joey

5
Cevabınızı biraz geliştirmek için ... "if" ifadelerini açıkça yerleştirmeniz gerekmez ... Dave Jarvis'in aşağıda gösterdiği gibi onları "zincirleyebilirsiniz"
JoelFan

Setten sonra herhangi bir boşluk bırakmamaya çalışın = true ya da sadece incelikle işe yaramaz. Değişkende "true" değerini
depolardı

1
Açıkladığınız 'veya' koşulu kaygan ve bir dizi sayı için harika çalışıyor, ancak bir aralık yerine 2 bağımsız değer karşılaştırıyorsam ne olur? Örneğin, bu dosya varsa veya dosya adı == ""
bakoyaro

1
@bakoyaro, bahsettikleriniz de dahil olmak üzere res değerini true olarak ayarlamak için herhangi bir koşulu kullanabilirsiniz.
paxdiablo

69

IFİfadesi mantıksal operatörler desteklemek (vermez ANDve ORbasamaklı) IFifadeleri örtük bir bağlaç olun.

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

Varsa File1.Dat ve File1.Dat varsa etiketi atlayınFILE12_EXIST_LABEL .

Ayrıca bakınız: IF /?


53

De Morgan yasaları , sadece bağlaçları ("VE") ve olumsuzlukları ("DEĞİL") kullanarak, sakatlıkları ("VEYA") mantıksal eşdeğerlere dönüştürmemize izin verir. Bu, diseksiyonları ("VEYA") bir hatta zincirleyebileceğimiz anlamına gelir.

Bu, ad "Yakko" veya "Wakko" veya "Dot" ise, "Warner kardeş veya kız kardeşi" yankısı anlamına gelir.

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

Bu, paxdiablo'nun "OR" örneğinin başka bir sürümüdür, ancak koşullar bir hatta zincirlenir. (Not tam tersi leqIS gtr, ve karşıt geqIS lss).

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

6

Aşağıdaki örnekler bir AND ifadesinin nasıl yapılacağını gösterir (değişkenleri ayarlamak veya bir komutun parametrelerini eklemek için kullanılır).

Not Defteri'ni başlatmak ve CMD penceresini kapatmak için:

start notepad.exe & exit

'A' değişkeni blah'a eşitse x, y ve z değişkenlerini değerlere ayarlamak için.

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

Umarım yardımcı olur!


5

VEYA biraz zor, ama aşırı değil. İşte bir örnek

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 (o sırada 16 yaşında), IF ifadelerindeki koşulları ortadan kaldırarak ve daha sonra ELSE yan tümcesini yürütülmesi gereken kodu koymak için konum olarak kullanarak bir OR testinin nasıl uygulanacağı hakkında mantıklı bir fikir verdi. Kendi kendime düşündüm, ancak iki IF deyimi kullanmayı önerdiği için genellikle iki cümle daha gerekli olduğunu ve bu nedenle yürütülen kodun iki kez yazılması gerektiğini düşündüm . Ancak, bir GOTO gerekli kodu atlamak için kullanılırsa, ELSE yan tümcelerini yazmak yerine yürütme kodunun yalnızca bir kez yazılması gerekir .

İşte bir OR oluşturmak için Athul Prakash'ın negatif mantığını nasıl uygulayacağımın test edilebilir bir örneği .

Benim örnekte, bir tankı lisansa sahip eğer birisi bir tank götürmek için izin verilir VEYA askerlik hizmetini yapıyor . İki isteme doğru veya yanlış girin , mantığın bir tankı kullanmanıza izin verip vermediğini görebilirsiniz.

@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

Bir ifadede bir if+ AND/ yazmak istiyorsanız, ORbunlardan hiçbiri yoktur. Ama, yine de grup olabilir ifile &&/ ||ve (/ )ifadeleri tek satırda istediğiniz ulaşmak için w / o herhangi bir ek değişkenler ve w / o if-elseblok çoğaltma (tek echokomut için TRUEve FALSEkod bölümleri):

@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

Çıktı :

TRUE+
FALSE-
FALSE-
FALSE-

TRUE+
TRUE+
TRUE+
FALSE-

Hile, typebırakan / ayarlayan errorlevelve böylece bir sonraki komuta giden yolu işleyen komuttadır.


1

Olumsuzlama işleneni deneyin - 'değil'!

Eğer iç içe 'deyimlerini kullanarak bir if deyiminde' VE 'işlemini gerçekleştirebiliyorsanız (önceki yanıtlara bakın), aynı işlemi' değilse 'ile bir' veya 'işlemi gerçekleştirebilirsiniz.

Henüz bu fikre sahip değilseniz okumaya devam edin. Aksi takdirde, zamanınızı boşa harcamayın ve programlamaya geri dönün.

Tıpkı 'tüm şartlar doğru olduğunda tatmin edilirse' iç içe geçtiği gibi, ancak tüm koşullar yanlış olduğunda tatmin edilemezse iç içe geçer. Bu, 'veya' işlenen ile yapmak istediğinize benzer, değil mi?

Yuvalanmış 'değilse' koşullarından herhangi biri doğru olsa bile, tüm ifade tatminsiz kalır. Bu nedenle, tüm iç içe koşullarınız yanlışsa, koşul ifadesinin gövdesinin yapmak istediğiniz şey olması gerektiğini hatırlayarak ihmal edilmişse 'art arda ise kullanabilirsiniz. Aslında vermek istediğiniz beden, başka bir ifadenin altında olmalıdır.

Ve eğer hala bir şey yapmazsan, üzgünüm, 16 yaşındayım ve açıklamak için yapabileceğim en iyisi bu.


x = 2 veya x = 3 =>! ! (x = 2 veya x = 3) =>! (x! = 2 ve x! = 3) Gerekli dış "değil" operatörünü uygulamak için tüm yapıyı reddedebileceğinizi düşünmüyorum. 3 yıl oldu, @ Athul-prakash, düşünceler?
Azeroth2b

1

Aşağıdaki kadar kolaydır:

AND> if + if

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

VEYA> 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*

Başka cevaplar olduğunu biliyorum, ama madenin daha basit, anlaşılması daha kolay olduğunu düşünüyorum. Umarım bu size yardımcı olur! ;)


0

Bir alternatif, size mantıksal işleçler ve çok daha fazlasını veren bir unix kabuğu aramaktır. Bir Bourne bir yerli win32 uygulaması kabuk alabilirsiniz burada cygwin rota gitmek istemiyorsanız. Yerel bir bash burada bulunabilir . Kolayca google zsh veya tcsh gibi diğer iyi alternatifleri google emin olabilirsiniz.

K


4
Farklı bir kabuk kullanma çabasından geçecekseniz, en azından PowerShell ile gidin: microsoft.com/powershell
Eclipse

17
DOS'tan çok daha iyi mermiler var. Bir DOS yarasa dosyası kullanmamın nedeni, herhangi bir harici araç gerektirmemesidir. Basit bir şeyi otomatikleştirmesi gereken bir müşteriniz varsa, bir BAT dosyasının yeterli olacağı zaman özel araçlar (cygwin, perl, powershell, vb.) Yüklemelerini gerçekten istiyor musunuz?
Mark Lakata

3
BAT çoğu zaman yeterlidir. Unix kabuk komut dosyalarının% 90'ı ppl write saf kabuk değil, birçok coreutils, sed, awk vb çağrıları ile. GNU, Windows da dahil olmak üzere diğer işletim sistemlerinde UNIX ürünlerini uyguladı. Bu getgnuwin32.sourceforge.net cmd.exe / bash / zsh artı bir göz atın artı bu çoğu görev için yeterli olmalıdır. BAT / UNIX Shell deneyiminiz varsa PowerShell'i öğrenmek için bir neden yok
MeaCulpa

0

Sadece OR kısmı zor, ancak NOT OR AND içeren genel bir boole ifadesi ile tek güzel çözüm şudur:

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

Yinelenen tip komutlarını azaltarak Andry'nin cevabında hafif değişiklik:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.