DOS 배치의 논리 연산자 ( "and", "or")


답변:


289

and중첩 된 조건으로 수행 할 수 있습니다 .

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

또는:

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

or별도의 변수로 할 수 있습니다 :

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

14
또한 바로 사용할 수 있습니다 set res=또는 set res=1다음과 if defined res좀 더 강력한 오타에 대하여이고 명시 적으로 지연 확장을 사용하지 않고 블록에서도 작동한다.
Joey

5
답변을 조금만 향상시키기 위해 ... "if"문을 명시 적으로 중첩 할 필요는 없습니다. Dave Jarvis가 아래에서 설명하는 것처럼 "chain"
만하면

set = true 뒤에 공백을 두지 마십시오. 그렇지 않으면 정상적으로 작동하지 않습니다. 변수에 "true"값을 저장합니다.
Roland Pihlakas

1
설명하는 '또는'조건은 매끄럽고 다양한 숫자에 효과적이지만 범위가 아닌 두 개의 독립적 인 값을 비교하면 어떻게됩니까? 예를 들어,이 파일이 존재하거나 filename == ""인 경우
bakoyaro

1
@bakoyaro, 언급 한 조건을 포함하여 모든 조건을 사용하여 res를 true로 설정할 수 있습니다.
paxdiablo

69

IF문은 논리 연산자 ( ANDOR)를 지원하지 않으며 계단식 IF문은 암시 적 연결을 만듭니다.

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

경우 File1.Dat File1.Dat 존재 다음 라벨을 점프 FILE12_EXIST_LABEL.

또한보십시오: IF /?


53

De Morgan의 법칙에 따라 연결 ( "AND")과 부정 ( "NOT") 만 사용하여 분리 ( "OR")를 논리적 등가로 변환 할 수 있습니다. 즉, 분리 ( "OR")를 한 줄에 연결할 수 있습니다.

이는 이름이 "Yakko"또는 "Wakko"또는 "Dot"인 경우 "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

이것은 paxdiablo의 "OR"예제의 다른 버전이지만 조건은 한 줄로 연결됩니다. (의 반대는 leqis gtr이고 반대는 geq입니다 lss.)

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

6

다음 예는 변수를 설정하거나 명령에 매개 변수를 포함하는 데 사용되는 AND 문 작성 방법을 보여줍니다.

메모장을 시작하고 CMD 창을 닫으려면

start notepad.exe & exit

변수 'a'가 blah와 같은 경우 변수 x, y 및 z를 값으로 설정합니다.

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

희망이 도움이됩니다!


5

OR은 약간 까다 롭지 만 지나치게 그렇지는 않습니다. 여기에 예가 있습니다

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 세)는 IF 문에서 조건을 무시한 다음 ELSE 절을 실행이 필요한 코드를 넣는 위치로 사용하여 OR 테스트를 구현하는 방법에 대한 논리적 아이디어를 제공했습니다. 나는 그가 두 개의 IF 문을 사용할 것을 제안했기 때문에 보통 두 개의 else 절이 필요하다고 생각했기 때문에 실행 된 코드는 두 번 작성해야합니다 . 그러나 GOTO를 사용하여 필요한 코드를 건너 뛰려면 ELSE 절을 작성하는 대신 실행 코드를 한 번만 작성 하면 됩니다.

다음은 Athul Prakash의 부정 논리를 구현하여 OR 을 만드는 방법에 대한 테스트 가능한 예입니다 .

내 예에서, 누군가 탱크 라이센스가 있거나 병역을하고 있다면 탱크를 운전할 수 있습니다 . 두 프롬프트에서 true 또는 false 를 입력 하면 로직으로 탱크를 운전할 수 있는지 여부를 확인할 수 있습니다.

@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

한 문장에 if+ AND/ 를 쓰려면 관심 OR이 없습니다. 그러나 / 및 / 문으로 그룹화 if하여 추가 변수 및 블록 복제 (단일 명령 및 코드 섹션) 없이 한 줄로 원하는 것을 얻을 수 있습니다 .&&||()if-elseechoTRUEFALSE

@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

출력 :

TRUE+
FALSE-
FALSE-
FALSE-

TRUE+
TRUE+
TRUE+
FALSE-

트릭은 type명령을 삭제 / 설정 errorlevel하고 다음 명령으로가는 길을 처리합니다.


1

부정 피연산자- 'not'을 사용해보십시오!

중첩 된 'if'를 사용하여 if 문에서 'AND'작업을 수행 할 수 있다면 (이전 답변 참조) 'if'와 동일한 작업을 수행하여 'or'작업을 수행 할 수 있습니다.

아이디어를 아직 얻지 못했다면 계속 읽으십시오. 그렇지 않으면 시간을 낭비하지 말고 프로그래밍으로 돌아가십시오.

모든 조건이 참일 때만 중첩 'if'가 충족되는 것처럼 모든 조건이 거짓 일 때만 중첩 'if'가 충족됩니다. 이것은 '또는'피연산자로하고 싶은 것과 비슷합니까?

중첩 된 '없는 경우'의 조건 중 하나라도 해당되는 경우에도 전체 내용은 충족되지 않습니다. 따라서 중첩 된 모든 조건이 거짓 인 경우 조건 문의 본문이 원하는 것이어야한다는 점을 기억하여 무시 된 'if'를 연속적으로 사용할 수 있습니다. 실제로주고 싶은 몸은 else 선언문 아래에 와야합니다.

그래도 여전히 문제를 해결하지 못했다면 미안합니다. 저는 16 살입니다. 제가 설명하기 위해 최선을 다하겠습니다.


x = 2 또는 x = 3 =>! ! (x = 2 또는 x = 3) =>! (x! = 2 and x! = 3) 필요한 외부 "not"연산자를 적용하기 위해 전체 구조를 부정 할 수 있다고 생각하지 않습니다. @ Athul-prakash, 3 년이 지 났어요?
Azeroth2b

1

다음과 같이 쉽습니다.

AND> if + if

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

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

나는 다른 대답이 있다는 것을 알고 있지만 광산은 더 간단하고 이해하기 쉽다고 생각합니다. 이것이 당신에게 도움이되기를 바랍니다! ;)


0

대안은 논리 연산자와 더 많은 것을 제공하는 유닉스 쉘을 찾는 것입니다. 당신은 Bourne 씨의 네이티브는 Win32 구현 쉘 얻을 수 있습니다 여기에 당신이 Cygwin에서 경로를 이동하지 않으려면. 네이티브 배쉬는 여기 에서 찾을 수 있습니다 . zsh 또는 tcsh와 같은 다른 좋은 대안을 쉽게 Google에 올릴 수 있다고 확신합니다.

케이


4
다른 셸을 사용하려는 경우 최소한 PowerShell을 사용하십시오. microsoft.com/powershell
Eclipse

17
DOS보다 더 나은 쉘이 있습니다. DOS bat 파일을 사용하는 이유는 외부 도구가 필요하지 않기 때문입니다. 간단한 것을 자동화해야하는 고객이있는 경우 BAT 파일로 충분할 때 특수 도구 (cygwin, perl, powershell 등)를 설치해야합니까?
마크 라 카타

3
BAT만으로도 충분합니다. 유닉스 쉘 스크립트 ppl write의 90 %는 순수 쉘이 아니지만 많은 coreutils, sed, awk 등의 호출을 가지고 있습니다. GNU는 Windows를 포함한 다른 OS에서 UNIX 기능을 구현했습니다. 따라서 getgnuwin32.sourceforge.net cmd.exe / bash / zsh를 살펴보면 대부분의 작업에서 충분합니다. BAT / UNIX Shell 경험이 있다면 소위 PowerShell을 배울 이유가 없습니다.
MeaCulpa

0

OR 부분 만 까다 롭지 만 NOT OR AND를 포함하는 일반적인 부울 식의 유일한 해결책은 다음과 같습니다.

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

Andry의 답변을 약간 수정하여 중복 유형 명령을 줄입니다.

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.