programing

만약... 또는 만약...윈도 배치파일에서

lastmoon 2023. 4. 17. 22:15
반응형

만약... 또는 만약...윈도 배치파일에서

윈도 배치파일에 IF 또는 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 문의 WinXP Batch Script에서 OR을 사용하는 것과 거의 동일한 답변을 가진 중복된 질문입니다.

최종 부록 - 변수가 대소문자를 구분하지 않는 값 목록 중 하나인지 테스트하기 위해 가장 좋아하는 기술을 거의 잊어버렸습니다.허용 가능한 값의 구분된 목록을 포함하는 테스트 변수를 초기화하고 검색 및 바꾸기를 사용하여 변수가 목록 내에 있는지 테스트합니다.이것은 매우 빠르고 임의로 긴 목록에 최소 코드를 사용합니다.지연된 확장(또는 CALL %%VAR%% 트릭)이 필요합니다.또한 테스트는 CASE INNSICTIVE입니다.

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 내의 예상 값에 따라 "sys="와 같은 옵션이 필요할 수 있습니다.

상기의 전략을 신뢰할 수 있는 것으로 합니다.=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%(예: 공백이나 특수문자)도요.^,&etc.이한 등을 한 에 대한 입니다. 이 솔루션의 다른 한 가지 제한사항은 지시 변수를 추가하지 않는 한 ELSE 절에 대한 옵션을 제공하지 않는다는 것입니다.하거나 대소문자를 하지 않는 입니다./I★★★★★★ 。

난 그렇게 생각 안 해.2개의 IF와 GOTO를 같은 라벨로 사용합니다.

IF cond1 GOTO foundit
IF cond2 GOTO foundit

ECHO Didn't find it
GOTO end

:foundit
ECHO Found it!

:end

"또는" 조건을 사용하기 위해 간단한 "FOR"를 한 줄로 사용할 수 있습니다.

FOR %%a in (item1 item2 ...) DO IF {condition_involving_%%a} {execute_command}  

고객님의 케이스에 적용:

FOR %%a in (1 2) DO IF %var%==%%a ECHO TRUE

두 번 실행 중지

된 것은 '아, 아, 아, '아예'입니다.{execute_command}2번입니다.이를 피하기 위해 첫 만남 후에 goto를 사용할 수 있습니다.

FOR %%a in (1 2) DO IF %var%==%%a (
    ECHO TRUE
    goto :continue
)
:continue 

{execute_command}두 번 실행될 수 있지만 원하지 않을 경우 추가만 하면 됩니다.&& goto :eof:

FOR %%a in (1 2) DO IF %var%==%%a ECHO TRUE && goto :eof

훨씬 단순하고, 여전히 단일 선상에 있습니다.

이 게시물 덕분에 많은 도움이 되었습니다.

도움이 될지 모르겠지만 문제가 생겼고, 덕분에 이 부울 등가성을 바탕으로 해결할 수 있는 또 다른 방법을 찾았습니다.

'A 또는 B'는 'not(A 및 B가 아님)'과 같다.

다음과 같이 됩니다.

IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE

이하가 됩니다.

IF not [%var%] == [1] IF not [%var%] == [2] ECHO FALSE

이 질문이 조금 오래된 질문이라도:

「 」를 사용하고 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회 실행할 수 있습니다.

IF <arg> OR ★★★★★★★★★★★★★★★★★」ELIF ★★★★★★★★★★★★★★★★★」ELSE IF,, 괄으......

이전 IF의 ELSE 안에 다른 IF를 중첩해 보십시오.

IF <arg> (
    ....
) ELSE (
    IF <arg> (
        ......
    ) ELSE (
        IF <arg> (
            ....
        ) 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

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 %x%==1 (
If %y%==1 (
:: both are equal to 1.
)
)

여러 변수의 값이 동일한지 확인하기 위한 것입니다.두 변수 중 하나에 대한 값입니다.

If %x%==1 (
:: true
)
If %x%==0 (
If %y%==1 (
:: true
)
)
If %x%==0 (
If %y%==0 (
:: False
)
)

난 그냥 내 머리 속에서 그 생각을 했어.좀 더 압축할 수 있어요.

이 질문이 오래된 것은 알고 있습니다만, 같은 질문을 하고 있는 다른 사람이 이 스레드를 발견했을 경우에 대비해 대체 솔루션을 투고하고 싶다고 생각하고 있습니다.변수를 에코하고 findstr을 사용하여 검증함으로써 OR 연산자의 부족을 해결할 수 있었습니다.

for /f %%v in ('echo %var% ^| findstr /x /c:"1" /c:"2"') do (
    if %errorlevel% equ 0 echo true
)

dbenham에 합니다.IF DEFINED체크하는 변수가 환경변수가 아닌 경우 문제가 발생할 수 있습니다.스크립트 변수는 이 특별한 취급을 받지 않습니다.

되어 있지 않은 BS처럼 수 , BS의 한 셸 한다.IFIF /?밝히다

정의된 조건은 환경 변수 이름을 사용하고 환경 변수가 정의된 경우 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가 없는 경우 사용합니다.다른 xcopy c:current/files g:bu/current 수식어가 /a 등입니다.어느 쪽인지 잘 모르겠어요.노트북 PC는 매장에 있습니다.사무실 컴퓨터도 있고난 거기 없어.

Windows XP에서 동작하는 배치파일을 취득하지 못했습니다.

내가 보통 사용하는 훨씬 더 빠른 대안은 다음과 같다. 가변 공간에 들어갈 수 있는 임의의 수의 조건을 "또는" 수 있기 때문이다.

@(
  Echo off
  Set "_Match= 1 2 3 "
)

Set /a "var=3"

Echo:%_Match%|Find " %var% ">nul || (
  REM Code for a false condition goes here
) && (
  REM code for a true condition goes here.
)

매우 간단합니다. 아래를 사용하세요.

IF %var% == 1 (
ECHO TRUE)

IF %var% == 2 (
ECHO TRUE)

다른 인 ''를 입니다.FINDSTR:

FINDSTR "hello there" x.y는 파일 x.y에서 "hello" 또는 "there"를 검색합니다.

그렇게

SET | FINDSTR /I /X "var=1 var=2" >NUL
IF %ERRORLEVEL% EQU 0 (
    ECHO TRUE
) ELSE (
    ECHO FALSE
)

어디에

/I    Specifies that the search is not to be case-sensitive.
/X    Prints lines that match exactly.

, 을 사용하세요.FINDSTR /R /I "^var=1$ ^var=2$" >NUL★★★★★★ 。

★★★★FINDSTR /R변수 문자열에 공백이 포함된 경우 다음과 같이 사용해야 합니다. FINDSTR /R /I "^var=1 a$ ^var=2 b$" >NUL를 클릭합니다.

, : ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,FINDSTR /I /X /C:"var=1 a" /C:"var=2 b" >NUL.

OR 연산자는 없지만 쓸 수 있습니다(의사 코드).

IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE

맘에 들다

IF "%var%" == "1" SET "match=y"
IF "%var%" == "2" SET "match=y"
IF DEFINED match ECHO TRUE

var가 정의되지 않은 경우 큰따옴표로 인해 구문 오류가 트리거되지 않습니다.

인라인 블록에서 사용할 수 있도록 IF를 호출 가능하고 깔끔하게 추상화한 외부 함수를 구축하여 보그단의 솔루션을 한 단계 높였습니다.어차피 배치 도서관을 짓는다면 더 이상 보지 마세요.

lib.displaces

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS
SHIFT & GOTO:%1
: Common batch extension library.

:::
: Performs conditional processing in batch programs. Is callable for inline use.
: Arguments:
:   %1 - /I for case-insensitive comparison on strings, can be skipped for case-sensitive comparison.
:   %2 - NOT to negate the result, can be skipped.
:   %3 - EXIST for file checks or first string to compare with, also supports "string1"=="string2" (full condition).
:   %4 - If EXIST is specified, path to the directory or file. 
:        Otherwise if %3 is not a full condition, this argument has to be one of:
:        - ==   Compares both strings to be equal using lstrcmpW or lstrcmpiW (case-insensitive).
:        - EQU  Converts both strings to numbers and checks if they are equal. 
:        - NEQ  Converts both strings to numbers and checks if they are not equal.
:        - LSS  Converts both strings to numbers and checks if the first is lesser than the second.
:        - LEQ  Converts both strings to numbers and checks if the first is lesser or equal than the second.
:        - GTR  Converts both strings to numbers and checks if the first is greater than the second.
:        - GEQ  Converts both strings to numbers and checks if the first is greater or equal than the second.
:        If a string cannot be parsed to a number, its numeric representation will be used. 
:        This argument can be skipped, so == will be used.
:   %5 - If %3 is not a full condition, this argument has to be the second string to compare.
: Outputs:
:   Nothing
: Returns:
:   0, if the condition is met, 1 otherwise
:::
:test-if
IF "%~1"=="/I" SET "I=/I " & SHIFT
IF "%~1"=="/i" SET "I=/I " & SHIFT
IF "%~1"=="NOT" SET "NOT=NOT " & SHIFT
IF "%~1"=="not" SET "NOT=NOT " & SHIFT
IF "%~1"=="EXIST" SET "EXIST=EXIST " & SHIFT
IF "%~1"=="exist" SET "EXIST=EXIST " & SHIFT

SET "string1=%~1%"
IF "%~3"=="" (
    SET "comp=^=^="
    SET "string2=%~2"
) ELSE (
    SET "comp=%~2"
    SET "string2=%~3"
)
IF %I%%NOT%%EXIST% "%string1%" %comp% "%string2%" (
    ENDLOCAL & EXIT /B 0
)
ENDLOCAL & EXIT /B 1

사용.

( ( CALL lib test-if "%1" == "foo" ) || ( CALL lib test-if "%1" == "bar" ) ) && (
    ECHO "Argument is foo or bar"
)
  • lib lib.subscases의 입니다..cmd.
  • 이 이 추상화와 할 수 .test-if EXIST "path" ★★★★★★★★★★★★★★★★★」test-if not 300 LSS 200
  • ==test-if "%1" == "foo"는 이 , 이 사실이 발생하게 됩니다.test-if "%1" "foo"하지만 그건 기준이 아니에요.

이것은 오래된 질문이라는 것을 깨달았기 때문에, 그 답변에 의해서, 커맨드 라인 인수를 배치 파일에 테스트하기 위한 솔루션을 생각해 낼 수 있었습니다.따라서, 다른 사람이 같은 솔루션을 찾고 있는 경우를 대비해, 제 솔루션을 투고하고 싶었습니다.

내가 가장 먼저 지적해야 할 것은 만약을 얻는 데 문제가 있었다는 것이다.ELSE 스테이트먼트는 FOR... 내에서 동작합니다.DO 조항(예를 들어 실수로 이것을 지적한 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

이것은 첫 번째 실패한 인수에 대해서만 보고됩니다.따라서 사용자가 둘 이상의 허용되지 않는 인수를 전달하면 첫 번째 인수가 수정될 때까지 두 번째 인수에 대해서만 알립니다.

언급URL : https://stackoverflow.com/questions/8438511/if-or-if-in-a-windows-batch-file

반응형