Các toán tử logic (mạng và hung, trên mạng hoặc trên nền tảng DOS)


Câu trả lời:


289

Bạn có thể làm andvới điều kiện lồng nhau:

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

hoặc là:

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

Bạn có thể làm orvới một biến riêng biệt:

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

14
Bạn cũng có thể chỉ sử dụng set res=hoặc set res=1sau if defined resđó mạnh hơn một chút so với lỗi chính tả và hoạt động ngay cả trong các khối mà không cho phép mở rộng chậm trễ.
Joey

5
Chỉ cần cải thiện câu trả lời của bạn một chút ... bạn không cần phải lồng một cách rõ ràng các câu lệnh "nếu" ... bạn có thể "xâu chuỗi" chúng, như Dave Jarvis trình bày dưới đây
JoelFan

Befare không để lại bất kỳ khoảng trắng nào sau tập hợp = true hoặc điều chỉ duyên dáng không hoạt động. Nó sẽ lưu trữ giá trị "đúng" trong biến ...
Roland Pihlakas

1
Điều kiện 'hoặc' bạn mô tả là trơn tru và hoạt động tốt cho một phạm vi số, nhưng nếu tôi so sánh 2 giá trị độc lập và không phải là một phạm vi thì sao? Ví dụ: nếu tệp này tồn tại hoặc tên tệp == ""
bakoyaro

1
@bakoyaro, bạn có thể sử dụng bất kỳ điều kiện nào để đặt độ phân giải thành true, bao gồm cả những điều bạn đề cập.
paxdiablo

69

Câu IFlệnh không hỗ trợ các toán tử logic ( ANDOR), các IFcâu lệnh xếp tầng tạo thành một kết hợp ngầm.

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

Nếu File1.Dat File1.Dat tồn tại thì nhảy nhãn FILE12_EXIST_LABEL.

Xem thêm: IF /?


53

Luật của De Morgan cho phép chúng tôi chuyển đổi các bất đồng ("HOẶC") thành các tương đương logic bằng cách chỉ sử dụng các liên từ ("VÀ") và phủ định ("KHÔNG"). Điều này có nghĩa là chúng ta có thể xâu chuỗi các bất đồng ("HOẶC") trên một dòng.

Điều này có nghĩa là nếu tên là "Yakko" hoặc "Wakko" hoặc "Dot", sau đó lặp lại "Anh chị em 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

Đây là một phiên bản khác của ví dụ "HOẶC" của paxdiablo, nhưng các điều kiện được nối vào một dòng. (Lưu ý rằng điều ngược lại leqgtrvà ngược lại geqlss.)

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

6

Các ví dụ sau đây cho thấy cách tạo câu lệnh AND (được sử dụng để đặt biến hoặc bao gồm các tham số cho lệnh).

Để bắt đầu Notepad và đóng cửa sổ CMD:

start notepad.exe & exit

Để đặt các biến x, y và z thành các giá trị nếu biến 'a' bằng blah.

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

Mong rằng sẽ giúp!


5

HOẶC hơi khó, nhưng không quá. Đây là một ví dụ

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 tuổi vào thời điểm đó) đã đưa ra một ý tưởng hợp lý về cách thực hiện kiểm tra OR bằng cách phủ định các điều kiện trong các câu lệnh IF và sau đó sử dụng mệnh đề ELSE làm vị trí để đặt mã yêu cầu thực thi. Tôi tự nghĩ rằng có hai mệnh đề khác thường cần thiết vì anh ta đề nghị sử dụng hai câu lệnh IF và do đó, mã thực thi cần phải được viết hai lần . Tuy nhiên, nếu một GOTO được sử dụng để bỏ qua mã được yêu cầu, thay vì viết ELSE, mệnh đề thực thi chỉ cần được viết một lần .

Dưới đây là một ví dụ có thể kiểm chứng về cách tôi sẽ triển khai logic phủ định của Athul Prakash để tạo OR .

Trong ví dụ của tôi, ai đó được phép lái xe tăng nếu họ có bằng lái xe tăng HOẶC họ đang thực hiện nghĩa vụ quân sự . Nhập đúng hoặc sai theo hai lời nhắc và bạn sẽ có thể xem liệu logic có cho phép bạn lái xe tăng hay không.

@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

Nếu bạn quan tâm để viết một câu lệnh if+ AND/ ORtrong một, thì không có câu nào trong số đó. Tuy nhiên, bạn vẫn có thể nhóm ifvới &&/ ||(/ các )câu lệnh để đạt được điều bạn muốn trong một dòng với bất kỳ biến bổ sung nào và if-elsesao chép khối w / o ( echolệnh đơn TRUEFALSEphần mã):

@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

Đầu ra :

TRUE+
FALSE-
FALSE-
FALSE-

TRUE+
TRUE+
TRUE+
FALSE-

Thủ thuật là trong typelệnh thả / thiết lập errorlevelvà do đó xử lý đường đến lệnh tiếp theo.


1

Hãy thử toán hạng phủ định - 'không'!

Chà, nếu bạn có thể thực hiện thao tác 'VÀ' trên câu lệnh if bằng cách sử dụng 'if lồng nhau (tham khảo các câu trả lời trước), thì bạn có thể làm điều tương tự với' nếu không 'để thực hiện thao tác' hoặc '.

Nếu bạn chưa có ý tưởng nào, hãy đọc tiếp. Nếu không, đừng lãng phí thời gian của bạn và quay lại lập trình.

Cũng như lồng nhau 'nếu chỉ được thỏa mãn khi tất cả các điều kiện là đúng, lồng nhau' nếu không được thỏa mãn chỉ khi tất cả các điều kiện là sai. Điều này tương tự với những gì bạn muốn làm với toán hạng 'hoặc', phải không?

Ngay cả khi bất kỳ một trong những điều kiện trong 'nếu không' được lồng nhau là đúng, toàn bộ tuyên bố vẫn không thỏa mãn. Do đó, bạn có thể sử dụng phủ định 'nếu liên tiếp bằng cách nhớ rằng phần thân của câu lệnh điều kiện sẽ là những gì bạn muốn làm nếu tất cả các điều kiện lồng nhau của bạn là sai. Cơ thể mà bạn thực sự muốn cho nên đến theo tuyên bố khác.

Và nếu bạn vẫn không hiểu ý chính, xin lỗi, tôi 16 tuổi và đó là điều tốt nhất tôi có thể làm để giải thích.


x = 2 hoặc x = 3 =>! ! (x = 2 hoặc x = 3) =>! (x! = 2 và x! = 3) Tôi không nghĩ bạn có thể phủ định toàn bộ cấu trúc if để áp dụng toán tử "không" bên ngoài cần thiết. Đã 3 năm rồi, @ Athul-prakash, suy nghĩ?
Azeroth2b

1

Nó chỉ dễ dàng như sau:

VÀ> nếu + nếu

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

HOẶC> nếu // nếu

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*

Tôi biết rằng có những câu trả lời khác, nhưng tôi nghĩ rằng cái này đơn giản hơn, nên dễ hiểu hơn. Hy vọng điều này sẽ giúp bạn! ;)


0

Một cách khác là tìm kiếm một vỏ unix cung cấp cho bạn các toán tử logic và nhiều thứ khác. Bạn có thể nhận bản triển khai win32 riêng của trình bao Bourne tại đây nếu bạn không muốn đi theo lộ trình cygwin. Một bash bản địa có thể được tìm thấy ở đây . Tôi khá chắc chắn rằng bạn có thể dễ dàng google các lựa chọn thay thế tốt khác như zsh hoặc tcsh.

K


4
Nếu bạn đang trải qua nỗ lực sử dụng một trình bao khác, ít nhất hãy đi với PowerShell: microsoft.com/powershell
Eclipse

17
Có nhiều shell tốt hơn DOS. Lý do tại sao tôi sử dụng tệp bat của DOS là vì nó không yêu cầu bất kỳ công cụ bên ngoài nào. Nếu bạn có một khách hàng cần tự động hóa một cái gì đó đơn giản, bạn có thực sự muốn họ phải cài đặt các công cụ đặc biệt (cygwin, perl, powershell, v.v.) khi tệp BAT đủ?
Đánh dấu Lakata

3
BAT là đủ hầu hết thời gian. 90% các tập lệnh shell unix ppl write không phải là shell thuần mà có nhiều lệnh coreutils, sed, awk, v.v. GNU đã triển khai các tính năng UNIX trong các HĐH khác, bao gồm cả Windows. Vì vậy, hãy xem getgnuwin32.sourceforge.net cmd.exe / bash / zsh này cộng với điều này là đủ cho hầu hết các nhiệm vụ. Không có lý do để tìm hiểu cái gọi là PowerShell nếu bạn có trải nghiệm BAT / UNIX Shell
MeaCulpa

0

Chỉ có phần OR là khó, nhưng với biểu thức boolean chung chứa KHÔNG HOẶC VÀ giải pháp tốt đẹp duy nhất là:

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

Sửa đổi nhẹ cho câu trả lời của Andry, giảm các lệnh loại trùng lặp:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.