Windows 배치 파일에 IF OR IF 조건문을 작성하는 방법이 있습니까?
예를 들면 :
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
답변:
zmbq 솔루션은 좋지만 FOR DO (...) 루프와 같은 코드 블록 내부와 같은 모든 상황에서 사용할 수는 없습니다.
대안은 인디케이터 변수를 사용하는 것입니다. 정의되지 않도록 초기화 한 다음 OR 조건 중 하나가 참인 경우에만 정의하십시오. 그런 다음 IF DEFINED를 최종 테스트로 사용합니다. 지연된 확장을 사용할 필요가 없습니다.
FOR ..... DO (
set "TRUE="
IF cond1 set TRUE=1
IF cond2 set TRUE=1
IF defined TRUE (
...
) else (
...
)
)
arasmussen이 첫 번째 조건이 참이면 조금 더 빨리 수행 할 수 있다는 이유로 사용하는 ELSE IF 논리를 추가 할 수 있지만, 저는 결코 신경 쓰지 않습니다.
부록 -IF 문에서 OR 사용 WinXP 배치 스크립트 와 거의 동일한 답변이있는 중복 질문입니다.
최종 부록 -변수가 대소 문자를 구분하지 않는 값 목록 중 하나인지 테스트하는 데 가장 좋아하는 기술을 거의 잊었습니다. 구분 된 허용 값 목록을 포함하는 테스트 변수를 초기화 한 다음 검색 및 바꾸기를 사용하여 변수가 목록 내에 있는지 테스트합니다. 이것은 매우 빠르고 임의로 긴 목록에 최소한의 코드를 사용합니다. 지연된 확장이 필요합니다 (또는 CALL %% VAR %% 트릭). 또한 테스트는 케이스에 민감하지 않습니다.
set "TEST=;val1;val2;val3;val4;val5;"
if "!TEST:;%VAR%;=!" neq "!TEST!" (echo true) else (echo false)
위의 내용은 VAR에이 포함되어 있으면 실패 할 수 =
있으므로 테스트는 절대 불가능합니다.
VAR의 현재 값에 액세스하기 위해 지연된 확장이 필요한 블록 내에서 테스트를 수행하는 경우
for ... do (
set "TEST=;val1;val2;val3;val4;val5;"
for /f %%A in (";!VAR!;") do if "!TEST:%%A=!" neq "!TEST!" (echo true) else (echo false)
)
VAR 내의 예상 값에 따라 "delims ="와 같은 FOR 옵션이 필요할 수 있습니다.
위의 전략은 =
코드를 조금 더 추가하여 VAR 에서도 안정적으로 만들 수 있습니다 .
set "TEST=;val1;val2;val3;val4;val5;"
if "!TEST:;%VAR%;=!" neq "!TEST!" if "!TEST:;%VAR%;=;%VAR%;"=="!TEST!" echo true
그러나 이제 우리는 표시기 변수를 추가하지 않는 한 ELSE 절을 제공하는 능력을 잃었습니다. 코드가 약간 "보기 흉하게"보이기 시작했지만 VAR이 임의의 수의 대소 문자를 구분하지 않는 옵션 중 하나인지 테스트하는 데 가장 신뢰할 수있는 방법이라고 생각합니다.
마지막으로 각 값에 대해 하나의 IF를 수행해야하기 때문에 약간 느리다고 생각하는 더 간단한 버전이 있습니다. Aacini는 이전에 언급 된 링크에서 수락 된 답변에 대한 의견으로이 솔루션을 제공했습니다.
for %%A in ("val1" "val2" "val3" "val4" "val5") do if "%VAR%"==%%A echo true
값 목록에는 * 또는? 문자 및 값과 %VAR%
따옴표를 포함해서는 안됩니다. (가) 경우 따옴표 문제가 발생할 %VAR%
또한 공백이나 같은 특수 문자가 포함되어 ^
, &
이 솔루션은 표시기 변수를 추가하지 않는 한이 ELSE 절에 대한 옵션을 제공하지 않습니다이다와 등 또 다른 한계를. 장점은 IF /I
옵션의 유무에 따라 대소 문자를 구분하거나 구분하지 않을 수 있다는 것입니다.
나는 그렇게 생각하지 않는다. 두 개의 IF 및 GOTO를 동일한 레이블로 사용하십시오.
IF cond1 GOTO foundit
IF cond2 GOTO foundit
ECHO Didn't found it
GOTO end
:foundit
ECHO Found it!
:end
ECHO Didn't find it
발견하더라도 타격을 입을 것입니다.
이 게시물에 감사드립니다. 많은 도움이되었습니다.
도움이 될 수 있다면 Dunno는 문제가 있었으며 덕분 에이 부울 등가를 기반으로 해결하는 또 다른 방법이라고 생각하는 것을 발견했습니다.
"A 또는 B"는 "not (A 아님 B 아님)"과 동일합니다.
그러므로:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
된다 :
IF not [%var%] == [1] IF not [%var%] == [2] ECHO FALSE
간단한 "FOR"을 한 줄에 사용하여 "or"조건을 사용할 수 있습니다.
FOR %%a in (item1 item2 ...) DO IF {condition_involving_%%a} {execute_command}
귀하의 사례에 적용 :
FOR %%a in (1 2) DO IF %var%==%%a ECHO TRUE
이 질문이 조금 더 오래된 경우에도 :
사용하고 싶다면 if cond1 or cond 2
-복잡한 루프 나 그런 것들을 사용해서는 안됩니다.
단순함 ifs
과 결합 된 후 둘 다 제공 goto
하는 것은 암시 적 또는입니다.
//thats an implicit IF cond1 OR cond2 OR cond3
if cond1 GOTO doit
if cond2 GOTO doit
if cond3 GOTO doit
//thats our else.
GOTO end
:doit
echo "doing it"
:end
goto없이 "inplace"작업이 없으면 모든 조건이 일치하면 작업을 3 번 실행할 수 있습니다.
OR 논리를 평가하고 단일 값을 반환하는 함수를 사용할 수 있습니다.
@echo off
set var1=3
set var2=5
call :logic_or orResult "'%var1%'=='4'" "'%var2%'=='5'"
if %orResult%==1 (
echo At least one expression is true
) ELSE echo All expressions are false
exit /b
:logic_or <resultVar> expression1 [[expr2] ... expr-n]
SETLOCAL
set "logic_or.result=0"
set "logic_or.resultVar=%~1"
:logic_or_loop
if "%~2"=="" goto :logic_or_end
if %~2 set "logic_or.result=1"
SHIFT
goto :logic_or_loop
:logic_or_end
(
ENDLOCAL
set "%logic_or.resultVar%=%logic_or.result%"
exit /b
)
&& ... || ...
추가 IF ... ELSE ...
문 대신 편리한 구문을 직접 사용할 수 있습니다 .
IF를 간접적으로 사용하여 목표를 달성 할 수 있습니다.
다음은 일관성없는 레이블 및 GOTO없이 CMD 배치에서 매우 간결하고 논리적으로 작성할 수있는 복잡한 표현식의 예입니다.
() 괄호 사이의 코드 블록은 CMD에서 (심각한) 종류의 서브 쉘로 처리됩니다. 블록에서 나오는 모든 종료 코드는 더 큰 부울 표현식에서 블록이 재생하는 참 / 거짓 값을 결정하는 데 사용됩니다. 이러한 코드 블록을 사용하여 임의로 큰 부울 식을 작성할 수 있습니다.
간단한 예
각 블록은 전체 표현식의 값이 결정되거나 제어가 점프 할 때까지 (예 : GOTO를 통해) true (예 : 블록의 마지막 문이 실행 된 후 ERRORLEVEL = 0) / false로 확인됩니다.
((DIR c:\xsgdde /w) || (DIR c:\ /w)) && (ECHO -=BINGO=-)
복잡한 예
이것은 처음에 제기 된 문제를 해결합니다. 각 블록에서 여러 문장이 가능하지만 || || || 가능한 한 읽을 수 있도록 간결하게하는 것이 좋습니다. ^는 CMD 배치의 이스케이프 문자이며 행 끝에 배치되면 EOL을 이스케이프하고 CMD가 다음 행에서 현재 배치의 문을 계속 읽도록 지시합니다.
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
(
(CALL :ProcedureType1 a b) ^
|| (CALL :ProcedureType2 sgd) ^
|| (CALL :ProcedureType1 c c)
) ^
&& (
ECHO -=BINGO=-
GOTO :EOF
)
ECHO -=no bingo for you=-
GOTO :EOF
:ProcedureType1
IF "%~1" == "%~2" (EXIT /B 0) ELSE (EXIT /B 1)
GOTO :EOF (this line is decorative as it's never reached)
:ProcedureType2
ECHO :ax:xa:xx:aa:|FINDSTR /I /L /C:":%~1:">nul
GOTO :EOF
dbenham의 대답은 꽤 좋지만 IF DEFINED
확인하는 변수가 환경 변수 가 아닌 경우 의존 하면 많은 문제가 발생할 수 있습니다 . 스크립트 변수는이 특별한 취급을받지 않습니다.
이것은 우스꽝스럽고 문서화되지 않은 BS처럼 보일 수 있지만 간단한 쉘 쿼리를 수행하면 다음 IF
과 같은 IF /?
사실이 드러납니다.
DEFINED 조건은 환경 변수 이름을 취하고 환경 변수가 정의 된 경우 true를 반환 한다는 점을 제외하면 EXIST와 동일하게 작동합니다 .
이 질문에 대한 답변과 관련하여 일련의 평가 후에 단순한 플래그를 사용하지 않는 이유가 있습니까? 그것은 OR
기본 논리와 가독성 측면에서 나에게 가장 유연한 검사 처럼 보입니다 . 예를 들면 :
Set Evaluated_True=false
IF %condition_1%==true (Set Evaluated_True=true)
IF %some_string%=="desired result" (Set Evaluated_True=true)
IF %set_numerical_variable% EQ %desired_numerical_value% (Set Evaluated_True=true)
IF %Evaluated_True%==true (echo This is where you do your passing logic) ELSE (echo This is where you do your failing logic)
분명히 그들은 어떤 종류의 조건부 평가가 될 수 있지만 몇 가지 예를 공유하고 있습니다.
모든 것을 한 줄에 서면으로 작성하고 &&
싶다면 다음 과 같이 연결하면됩니다 .
Set Evaluated_True=false
IF %condition_1%==true (Set Evaluated_True=true) && IF %some_string%=="desired result" (Set Evaluated_True=true) && IF %set_numerical_variable% EQ %desired_numerical_value% (Set Evaluated_True=true)
IF %Evaluated_True%==true (echo This is where you do your passing logic) ELSE (echo This is where you do your failing logic)
일하기 위해 존재하지 않았습니다.
존재하지 않는 경우 g : xyz / what goto h를 사용합니다. Else xcopy c : current / files g : bu / current 수정 자 / a 등이 있습니다. 어떤 것이 있는지 확실하지 않습니다. 상점에서 노트북. 그리고 사무실의 컴퓨터. 나는 거기에 없다.
Windows XP 이상에서 작동 할 배치 파일이 없습니다.
이것이 약간 오래된 질문이라는 것을 깨달은 응답은 배치 파일에 대한 명령 줄 인수를 테스트하는 솔루션을 찾는 데 도움이되었습니다. 그래서 다른 사람이 비슷한 솔루션을 찾고있는 경우를 대비하여 내 솔루션도 게시하고 싶었습니다.
가장 먼저 지적해야 할 점은 FOR ... DO 절 내에서 IF ... ELSE 문이 작동하도록하는 데 문제가 있다는 것입니다. (부주의하게 그의 예에서 이것을 지적한 dbenham에게 감사합니다) ELSE 문은 닫는 괄호와 별도의 줄에있을 수 없습니다.
그래서이 대신 :
FOR ... DO (
IF ... (
)
ELSE (
)
)
가독성과 미적 이유로 내가 선호하는 것은 다음과 같습니다.
FOR ... DO (
IF ... (
) ELSE (
)
)
이제 ELSE 문은 인식 할 수없는 명령으로 반환되지 않습니다.
마지막으로, 제가하려는 작업은 다음과 같습니다. 순서에 상관없이 배치 파일에 여러 인수를 전달하고, 케이스를 무시하고, 전달 된 정의되지 않은 인수에 대해보고 / 실패 할 수 있기를 원했습니다. 그래서 여기에 제 해결책이 있습니다.
@ECHO OFF
SET ARG1=FALSE
SET ARG2=FALSE
SET ARG3=FALSE
SET ARG4=FALSE
SET ARGS=(arg1 Arg1 ARG1 arg2 Arg2 ARG2 arg3 Arg3 ARG3)
SET ARG=
FOR %%A IN (%*) DO (
SET TRUE=
FOR %%B in %ARGS% DO (
IF [%%A] == [%%B] SET TRUE=1
)
IF DEFINED TRUE (
SET %%A=TRUE
) ELSE (
SET ARG=%%A
GOTO UNDEFINED
)
)
ECHO %ARG1%
ECHO %ARG2%
ECHO %ARG3%
ECHO %ARG4%
GOTO END
:UNDEFINED
ECHO "%ARG%" is not an acceptable argument.
GOTO END
:END
이것은 첫 번째 실패한 인수에 대해서만보고합니다. 따라서 사용자가 허용되지 않는 인수를 두 개 이상 전달하면 수정 될 때까지 첫 번째 인수에 대한 정보 만 전달되고 두 번째 인수에 대한 정보 만 전달됩니다.
IF [%var%]==[1] IF [%var2%]==[2] ECHO BOTH ARE TRUE
입니다. 나는 정의SET AND=IF
하고 다음과 같이 작성했습니다IF cond1 %AND% cond2 ECHO BOTH ARE TRUE
.