Operator logis ("dan", "atau") dalam batch DOS

Jawaban:

289

Anda dapat melakukannya anddengan kondisi bersarang:

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

atau:

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

Anda dapat melakukannya ordengan variabel terpisah:

set res=F
if %hour% leq 6 set res=T
if %hour% geq 22 set res=T
if "%res%"=="T" (
    set state=asleep
)
paxdiablo
sumber
14
Anda juga bisa menggunakan set res=atau set res=1kemudian if defined resyang sedikit lebih kuat terhadap kesalahan ketik dan bekerja bahkan dalam blok tanpa secara eksplisit memungkinkan ekspansi tertunda.
Joey
5
Hanya untuk sedikit meningkatkan jawaban Anda ... Anda tidak perlu secara eksplisit menyarang pernyataan "jika" ... Anda hanya dapat "rantai" mereka, seperti yang ditunjukkan Dave Jarvis di bawah ini
JoelFan
Jangan meninggalkan ruang apa pun setelah himpunan = benar atau hal yang anggun tidak berfungsi. Itu akan menyimpan nilai "true" dalam variabel ...
Roland Pihlakas
1
Kondisi 'atau' yang Anda gambarkan adalah apik dan berfungsi bagus untuk rentang angka, tetapi bagaimana jika saya membandingkan 2 nilai independen, dan bukan rentang? Misalnya, jika file ini ada atau nama file == ""
bakoyaro
1
@bakoyaro, Anda dapat menggunakan kondisi apa pun untuk menyetel res menjadi true, termasuk yang Anda sebutkan.
paxdiablo
69

The IFpernyataan tidak mendukung operator logika ( ANDdan OR), Cascading IFpernyataan membuat hubungannya implisit.

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

Jika File1.Dat dan File1.Dat yang ada kemudian melompat label FILE12_EXIST_LABEL.

Lihat juga: IF /?

Dave Jarvis
sumber
53

Hukum De Morgan memungkinkan kita untuk mengubah disjunctions ("OR") menjadi padanan logis hanya menggunakan konjungsi ("AND") dan negations ("NOT"). Ini berarti kita dapat menghubungkan disjungsi ("OR") ke satu baris.

Ini berarti jika nama adalah "Yakko" atau "Wakko" atau "Dot", maka gema "Warner brother or sister".

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

Ini adalah versi lain dari contoh "OR" paxdiablo, tetapi kondisinya terikat pada satu baris. (Perhatikan bahwa kebalikan dari leqadalah gtr, dan kebalikan dari geqadalah lss.)

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

Contoh berikut menunjukkan cara membuat pernyataan AND (digunakan untuk mengatur variabel atau termasuk parameter untuk perintah).

Untuk memulai Notepad dan tutup jendela CMD:

start notepad.exe & exit

Untuk mengatur variabel x, y, dan z ke nilai jika variabel 'a' sama dengan bla.

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

Semoga itu bisa membantu!

GinDiamond
sumber
5

ATAU sedikit rumit, tetapi tidak terlalu rumit. Berikut ini sebuah contoh

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
sumber
2

Athul Prakash (usia 16 pada saat itu) memberikan ide logis tentang bagaimana menerapkan tes OR dengan meniadakan kondisi dalam pernyataan IF dan kemudian menggunakan klausa ELSE sebagai lokasi untuk meletakkan kode yang memerlukan eksekusi. Saya berpikir bahwa ada dua klausa lain yang biasanya diperlukan karena ia menyarankan untuk menggunakan dua pernyataan IF, sehingga kode yang dieksekusi perlu ditulis dua kali . Namun, jika GOTO digunakan untuk melewati kode yang diperlukan, alih-alih menulis klausa ELSE, kode untuk eksekusi hanya perlu ditulis satu kali .

Berikut adalah contoh yang dapat diuji tentang bagaimana saya akan menerapkan logika negatif Athul Prakash untuk membuat OR .

Dalam contoh saya, seseorang diizinkan untuk mengemudikan tank jika mereka memiliki lisensi tank ATAU mereka melakukan dinas militer mereka . Masukkan benar atau salah pada dua perintah dan Anda akan dapat melihat apakah logika memungkinkan Anda untuk menggerakkan tangki.

@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
sumber
2

Jika Anda tertarik untuk menulis if+AND / ORdalam satu pernyataan, maka tidak ada satupun. Namun, Anda masih dapat mengelompokkan ifdengan &&/ ||dan (/ )pernyataan untuk mencapai yang Anda inginkan dalam satu baris tanpa variabel tambahan dan tanpa if-elseduplikasi blok ( echoperintah tunggal untuk TRUEdan FALSEkode bagian):

@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

Output :

TRUE+
FALSE-
FALSE-
FALSE-

TRUE+
TRUE+
TRUE+
FALSE-

Triknya ada di typeperintah yang menjatuhkan / mengatur errorleveldan menangani jalan ke perintah berikutnya.

Andry
sumber
1

Coba operan negasi - 'tidak'!

Nah, jika Anda dapat melakukan operasi 'DAN' pada pernyataan if menggunakan nested 'if's (rujuk jawaban sebelumnya), maka Anda dapat melakukan hal yang sama dengan' jika tidak 'untuk melakukan operasi' atau '.

Jika Anda belum mendapatkan idenya, baca terus. Jika tidak, jangan buang waktu Anda dan kembali ke pemrograman.

Sama seperti 'jika puas hanya ketika semua kondisi benar, bersarang' jika tidak puas hanya ketika semua kondisi salah. Ini mirip dengan apa yang ingin Anda lakukan dengan operan 'atau', bukan?

Bahkan ketika salah satu kondisi dalam bersarang 'jika tidak' benar, seluruh pernyataan tetap tidak puas. Oleh karena itu, Anda dapat menggunakan negasi 'jika berturut-turut dengan mengingat bahwa isi pernyataan kondisi harus menjadi apa yang ingin Anda lakukan jika semua kondisi bersarang Anda salah. Tubuh yang sebenarnya ingin Anda berikan harus berada di bawah pernyataan lain.

Dan jika Anda masih tidak mendapatkan inti masalahnya, maaf, saya 16 dan itu yang terbaik yang bisa saya lakukan untuk menjelaskan.

Athul Prakash
sumber
x = 2 atau x = 3 =>! ! (x = 2 atau x = 3) =>! (x! = 2 dan x! = 3) Saya tidak berpikir Anda dapat meniadakan keseluruhan jika struktur untuk menerapkan operator luar "tidak" yang diperlukan. Sudah 3 tahun, @ Athul-prakash, pikiran?
Azeroth2b
1

Ini semudah yang berikut ini:

DAN> jika + jika

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

ATAU> jika // jika

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*

Saya tahu bahwa ada jawaban lain, tetapi saya pikir tambang itu lebih sederhana, jadi lebih mudah dimengerti. Semoga ini bisa membantu Anda! ;)

Perangkat Lunak Renk
sumber
0

Alternatifnya adalah mencari shell unix yang memang memberi Anda operator logis dan banyak lagi. Anda bisa mendapatkan implementasi win32 asli dari shell Bourne di sini jika Anda tidak ingin menggunakan rute cygwin. Pesta asli dapat ditemukan di sini . Saya cukup yakin Anda bisa dengan mudah mencari alternatif bagus lain seperti zsh atau tcsh.

K

Kevin Shea
sumber
4
Jika Anda akan melalui upaya menggunakan shell yang berbeda, setidaknya pergilah dengan PowerShell: microsoft.com/powershell
Eclipse
17
Ada banyak shell yang lebih baik daripada DOS. Alasan mengapa saya akan menggunakan file bat DOS adalah karena tidak memerlukan alat eksternal. Jika Anda memiliki pelanggan yang perlu mengotomatisasi sesuatu yang sederhana, apakah Anda benar-benar ingin mereka harus menginstal alat khusus (cygwin, perl, PowerShell, dll) ketika file BAT sudah cukup?
Mark Lakata
3
BAT cukup sering terjadi. 90% dari skrip shell unix ppl tulis bukan shell murni tetapi dengan banyak coreutils, sed, awk dll panggilan. GNU telah mengimplementasikan barang UNIX di OS lain, termasuk Windows. Jadi lihat cmd.exe getgnuwin32.sourceforge.net ini / bash / zsh plus ini harus cukup pada sebagian besar tugas. Tidak ada alasan untuk mempelajari apa yang disebut PowerShell jika Anda memiliki pengalaman BAT / UNIX Shell
MeaCulpa
0

Hanya bagian ATAU yang rumit, tetapi dengan ekspresi boolean umum yang mengandung BUKAN ATAU DAN satu-satunya solusi yang bagus adalah ini:

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
sumber
-1

Sedikit modifikasi pada jawaban Andry, mengurangi perintah tipe rangkap:

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
sumber