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 (
...
)
)
1番目の条件がtrueの場合、少し高速に実行される可能性があるという理由でarasmussenが使用するELSE IFロジックを追加できますが、私は気にしません。
補遺 -これは、IFステートメントでのORの使用WinXPバッチスクリプトとほぼ同じ回答の重複した質問です
最終補遺 -変数が大文字と小文字を区別しない値のリストのいずれかであるかどうかをテストするためのお気に入りのテクニックをほとんど忘れていました。許容値の送信済みリストを含むテスト変数を初期化し、検索と置換を使用して、変数がリスト内にあるかどうかをテストします。これは非常に高速で、任意の長いリストに対して最小限のコードを使用します。拡張の遅延が必要です(または、CALL %% VAR %%のトリック)。また、テストはCASE INSENSITIVEです。
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が大文字と小文字を区別しない任意の数のオプションのいずれかであるかどうかをテストするための、信頼性の高い最適な方法です。
最後に、値ごとに1つのIFを実行する必要があるため、少し遅いと思う単純なバージョンがあります。Aaciniは、前述のリンクで受け入れられた回答に対するコメントでこのソリューションを提供しました
for %%A in ("val1" "val2" "val3" "val4" "val5") do if "%VAR%"==%%A echo true
値のリストに*または?を含めることはできません。文字、値、および%VAR%
引用符を含めることはできません。場合は、引用符は問題につながる%VAR%
も、スペースなどの特殊文字が含まれている^
、&
この解決策の一つの他の制限は、あなたがインジケータ変数を追加しない限り、それはELSE句のオプションを提供していないですなど。利点は、IF /I
オプションの有無に応じて、大文字と小文字を区別する場合と区別しない場合があります。
私はそうは思いません。2つの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 or B」は「not(not A and not B)」と同じ
したがって:
IF [%var%] == [1] OR IF [%var%] == [2] ECHO TRUE
になる:
IF not [%var%] == [1] IF not [%var%] == [2] ECHO FALSE
単純な "FOR"を1行で使用して、 "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を使用せずに「インプレース」アクションを実行すると、すべての条件が一致する場合、アクションが3回実行される可能性があります。
何もありませんIF <arg> OR
かELIF
もしくはELSE IF
しかし、バッチで...
前のIFのELSE内に他のIFをネストしてみてください。
IF <arg> (
....
) ELSE (
IF <arg> (
......
) ELSE (
IF <arg> (
....
) ELSE (
)
)
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によって(哀れな)種類のサブシェルとして処理されます。ブロックから出てくる終了コードはすべて、ブロックがより大きなブール式で再生するtrue / false値を決定するために使用されます。これらのコードブロックを使用して、任意の大きなブール式を作成できます。
簡単な例
各ブロックは、式全体の値が決定されるか、制御がジャンプするまで(たとえば、GOTOを介して)、true(つまり、ブロックの最後のステートメントが実行された後はERRORLEVEL = 0)に解決されます。
((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
withの簡単なシェルクエリを実行すると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)
明らかに、それらはあらゆる種類の条件付き評価になる可能性がありますが、私はいくつかの例を共有しています。
すべてを1行で記述したい場合は、次のようにチェーンします&&
。
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
これは、失敗した最初の引数についてのみ報告することに注意してください。したがって、ユーザーが複数の許容できない引数を渡した場合、修正されるまで最初の引数のみが通知され、次に2番目の引数などが通知されます。
IF [%var%]==[1] IF [%var2%]==[2] ECHO BOTH ARE TRUE
。以前は以下を定義SET AND=IF
して記述していましたIF cond1 %AND% cond2 ECHO BOTH ARE TRUE
。