バッチファイルには || という OR 演算子がなく、OR 条件は フラグ変数 や else-if チェーン で実現します。AND 条件(IF の入れ子)と比べると書き方のパターンが多く、「どの方法を選ぶべきか」が迷いやすいポイントです。
この記事では OR 条件の全パターン を用途別に体系化し、コピーしてすぐ使える実践例を3本紹介します。
- フラグ変数方式でOR条件を書く方法(最も汎用的)
- else-if チェーンとフラグ変数の使い分け
- 数値・文字列・IF EXIST・ERRORLEVEL それぞれのOR結合
- FINDSTR を使ったOR条件(複数キーワード検索)
- 遅延展開との組み合わせ(FOR ループ内のOR判定)
- AND条件とOR条件の混在パターン
- NOT条件のOR(ド・モルガンの法則)
- 落とし穴5選・実践例3本・FAQ6問
- 1. OR条件の2つの基本パターン
- 2. フラグ変数方式(最も汎用的なOR)
- 3. else-if チェーン(条件ごとに処理が異なるOR)
- 4. 数値比較のOR
- 5. 文字列比較のOR
- 6. IF EXIST のOR(ファイル・フォルダ存在チェック)
- 7. ERRORLEVELのOR(複数コマンドのいずれかが失敗したら)
- 8. FINDSTR を使ったOR(文字列内容の複数キーワード検索)
- 9. 遅延展開との組み合わせ(FORループ内のOR判定)
- 10. AND条件とOR条件の混在パターン
- 11. NOT条件のORとド・モルガンの法則
- 12. 落とし穴5選と対策
- 13. 実践例3本
- 14. まとめ:OR条件パターン早見表
- FAQ
1. OR条件の2つの基本パターン
バッチの OR 条件には大きく2つのアプローチがあります。まず用途に応じた選び方を覚えましょう。
| パターン | 向いているケース | 特徴 |
|---|---|---|
| フラグ変数方式 | 複数条件のどれかが成立したら同じ処理をする | 条件を増やしやすい・AND混在可能 |
| else-if チェーン | 条件ごとに異なる処理をする(最初に成立したもの優先) | 処理が別々のときに読みやすい |
詳細は バッチファイルで条件分岐する方法完全ガイド と AND条件の完全ガイド もあわせて参照してください。
2. フラグ変数方式(最も汎用的なOR)
各条件が成立したら共通フラグを set し、最後にフラグの有無で判定するパターンです。条件の数が増えても読みやすく、AND との混在にも対応できます。
2-1. 基本構文
@echo off
set "MATCH="
:: いずれかの条件が成立したらフラグを立てる
if "%VAR%"=="A" set "MATCH=1"
if "%VAR%"=="B" set "MATCH=1"
if "%VAR%"=="C" set "MATCH=1"
:: フラグで OR 判定
if defined MATCH (
echo [OK] A・B・C のいずれかが成立しました
) else (
echo [NG] どの条件も成立しませんでした
)
2-2. 3つ以上の条件を OR で結合
@echo off
set "EXT=%~x1"
set "VALID="
if /i "%EXT%"==".csv" set "VALID=1"
if /i "%EXT%"==".tsv" set "VALID=1"
if /i "%EXT%"==".txt" set "VALID=1"
if /i "%EXT%"==".json" set "VALID=1"
if not defined VALID (
echo [ERROR] 対応していない拡張子です: %EXT%
echo 使用可能: .csv .tsv .txt .json
exit /b 1
)
echo [OK] %~nx1 を処理します
3. else-if チェーン(条件ごとに処理が異なるOR)
バッチには else if キーワードはありませんが、else (if ...) を使って実現できます。最初に成立した条件の処理だけが実行されます(短絡評価)。
3-1. 基本的な else-if チェーン
@echo off
set "STATUS=%~1"
if /i "%STATUS%"=="start" (
echo サービスを起動します
net start MyService
) else if /i "%STATUS%"=="stop" (
echo サービスを停止します
net stop MyService
) else if /i "%STATUS%"=="restart" (
echo サービスを再起動します
net stop MyService
net start MyService
) else (
echo [ERROR] 不明なコマンドです: %STATUS%
echo 使用可能: start / stop / restart
exit /b 1
)
3-2. else-if チェーンとフラグ変数の使い分け
:: else-if は「最初に成立した条件だけ実行」 :: → 複数の条件が成立しても1つ目だけ処理される if "%X%"=="A" (echo A) else if "%X%"=="B" (echo B) :: フラグ変数は「成立したすべての条件後に1回処理」 :: → 複数の条件を列挙して共通の処理をするのに向く if "%X%"=="A" set "OK=1" if "%X%"=="B" set "OK=1" if defined OK echo A または B が成立しました
4. 数値比較のOR
数値の OR は「特定の値かどうか」や「範囲外かどうか」などのパターンで使います。数値比較の完全ガイド もあわせて参照してください。
4-1. 特定の値のどれかに一致するOR
@echo off
set "CODE=%~1"
set "CRITICAL="
:: 致命的なエラーコード(1 または 2 または 5)かどうか
if %CODE% EQU 1 set "CRITICAL=1"
if %CODE% EQU 2 set "CRITICAL=1"
if %CODE% EQU 5 set "CRITICAL=1"
if defined CRITICAL (
echo [CRITICAL] 致命的なエラーコード: %CODE%
exit /b 1
)
echo [INFO] 通常コード: %CODE%
4-2. 範囲外チェック(下限未満 OR 上限超過)
@echo off
set /p PORT=ポート番号を入力:
:: 1〜65535 の範囲外なら OR でエラー
set "OUT_OF_RANGE="
if %PORT% LSS 1 set "OUT_OF_RANGE=1"
if %PORT% GTR 65535 set "OUT_OF_RANGE=1"
if defined OUT_OF_RANGE (
echo [ERROR] ポート番号が無効です: %PORT%(1〜65535 で指定してください)
exit /b 1
)
echo [OK] ポート %PORT% を使用します
5. 文字列比較のOR
文字列の OR は「複数の候補値のどれかに一致するか」のチェックに使います。文字列比較の方法 もあわせて参照してください。
5-1. 複数の文字列候補をORで確認
@echo off
set "DAY=%~1"
set "IS_HOLIDAY="
if /i "%DAY%"=="Saturday" set "IS_HOLIDAY=1"
if /i "%DAY%"=="Sunday" set "IS_HOLIDAY=1"
if /i "%DAY%"=="Holiday" set "IS_HOLIDAY=1"
if defined IS_HOLIDAY (
echo %DAY% は休日です。バッチ処理をスキップします
exit /b 0
)
echo %DAY% は平日です。処理を開始します
5-2. 空文字・未定義のどちらでもエラーにするOR
@echo off
set "INPUT=%~1"
:: 引数が未指定 または 空文字 の場合にエラー
set "ERR="
if "%INPUT%"=="" set "ERR=1"
if not defined INPUT set "ERR=1"
if defined ERR (
echo [ERROR] 引数を指定してください
exit /b 1
)
echo 引数: %INPUT%
6. IF EXIST のOR(ファイル・フォルダ存在チェック)
「複数のファイルのうち、どれかが存在すれば処理を進める」パターンです。IF EXISTの使い方 もあわせて参照してください。
@echo off
set "FOUND="
:: config.ini または config.yaml または .env のどれかが存在すればOK
if exist "config.ini" set "FOUND=config.ini"
if exist "config.yaml" set "FOUND=config.yaml"
if exist ".env" set "FOUND=.env"
if not defined FOUND (
echo [ERROR] 設定ファイルが見つかりません
echo config.ini / config.yaml / .env のいずれかを作成してください
exit /b 1
)
echo [OK] 設定ファイルを確認しました: %FOUND%
6-2. NOT EXIST のOR(どのファイルも存在しない = エラー)
@echo off
:: バックアップが1つも存在しない場合にエラー
set "HAS_BACKUP="
if exist "backup_daily.zip" set "HAS_BACKUP=1"
if exist "backup_weekly.zip" set "HAS_BACKUP=1"
if exist "backup_monthly.zip" set "HAS_BACKUP=1"
if not defined HAS_BACKUP (
echo [ALERT] バックアップファイルが1つも存在しません!
exit /b 1
)
echo [OK] バックアップを確認しました
7. ERRORLEVELのOR(複数コマンドのいずれかが失敗したら)
複数コマンドのうちどれかが失敗したかどうかを OR 判定するパターンです。ERRORLEVELを使ったエラーハンドリングもあわせて参照してください。
@echo off
setlocal
:: 複数コマンドを実行して ERRORLEVEL を保存
xcopy /y "C:\src\a.txt" "D:\dst\" >nul 2>&1
set "ERR1=%ERRORLEVEL%"
xcopy /y "C:\src\b.txt" "D:\dst\" >nul 2>&1
set "ERR2=%ERRORLEVEL%"
xcopy /y "C:\src\c.txt" "D:\dst\" >nul 2>&1
set "ERR3=%ERRORLEVEL%"
:: どれか1つでも失敗(ERRORLEVEL != 0)なら OR でエラー
set "ANY_FAIL="
if not %ERR1% EQU 0 set "ANY_FAIL=1"
if not %ERR2% EQU 0 set "ANY_FAIL=1"
if not %ERR3% EQU 0 set "ANY_FAIL=1"
if defined ANY_FAIL (
echo [ERROR] コピーに失敗したファイルがあります
if not %ERR1% EQU 0 echo - a.txt: ERRORLEVEL=%ERR1%
if not %ERR2% EQU 0 echo - b.txt: ERRORLEVEL=%ERR2%
if not %ERR3% EQU 0 echo - c.txt: ERRORLEVEL=%ERR3%
exit /b 1
)
echo [OK] すべてのコピーが成功しました
8. FINDSTR を使ったOR(文字列内容の複数キーワード検索)
ファイル内容や変数の値が複数キーワードのどれかを含むかどうかを OR で判定できます。FINDSTR の /c:"キーワード" を複数指定すると OR 検索になります。FINDSTRコマンドの完全ガイドも参照してください。
8-1. ファイル内容にキーワードのどれかが含まれるか
@echo off
:: ログファイルに ERROR・WARN・CRITICAL のどれかが含まれれば OR でアラート
findstr /i /c:"ERROR" /c:"WARN" /c:"CRITICAL" "C:\work\app.log" >nul 2>&1
if errorlevel 1 (
echo [OK] ログに異常は見つかりませんでした
) else (
echo [ALERT] ログに異常が検出されました
findstr /i /c:"ERROR" /c:"WARN" /c:"CRITICAL" "C:\work\app.log"
)
8-2. 変数の値が複数キーワードのどれかを含むか
@echo off
set "MESSAGE=%~1"
:: echo で出力した文字列に FINDSTR で OR 検索
echo %MESSAGE% | findstr /i /c:"error" /c:"fail" /c:"ng" >nul 2>&1
if not errorlevel 1 (
echo [WARN] エラーを示すキーワードが検出されました: %MESSAGE%
) else (
echo [OK] 問題なし: %MESSAGE%
)
9. 遅延展開との組み合わせ(FORループ内のOR判定)
FOR ループや IF ブロックの内側でフラグを更新して OR 判定するには遅延展開(!変数!)が必要です。setlocal enabledelayedexpansion 完全ガイド と 変数展開が動かない原因と修正方法 も参照してください。
@echo off
setlocal enabledelayedexpansion
set "HAS_TARGET="
:: ループ内でフラグを更新
for %%F in ("C:\work\*.log") do (
:: .log ファイルのどれかが 10KB 以上なら OR でフラグを立てる
if %%~zF GEQ 10240 (
set "HAS_TARGET=1"
echo 対象ファイル: %%~nxF (%%~zF bytes)
)
)
:: ループ後に OR 判定
if defined HAS_TARGET (
echo [OK] 10KB 以上のログが見つかりました。アーカイブ処理を開始します
) else (
echo [SKIP] 対象ファイルはありません
)
9-2. ループ内の即時OR判定(!変数! で遅延評価)
@echo off
setlocal enabledelayedexpansion
set "FOUND_TYPE="
for %%F in ("C:\work\*") do (
set "EXT=%%~xF"
:: 拡張子が .bat または .cmd のどれかなら即座にフラグ
if /i "!EXT!"==".bat" set "FOUND_TYPE=1"
if /i "!EXT!"==".cmd" set "FOUND_TYPE=1"
)
if defined FOUND_TYPE (
echo .bat または .cmd ファイルが存在します
)
10. AND条件とOR条件の混在パターン
「A かつ(B または C)」のような複合条件は、フラグ変数を組み合わせて段階的に評価します。
10-1. AND の中にOR を含む(A AND (B OR C))
@echo off
:: 条件: ENV==prod かつ (TYPE==csv OR TYPE==tsv)
set "ENV=prod"
set "TYPE=csv"
:: まず OR 部分をフラグに評価
set "TYPE_OK="
if /i "%TYPE%"=="csv" set "TYPE_OK=1"
if /i "%TYPE%"=="tsv" set "TYPE_OK=1"
:: AND: 両方の条件が成立するか
if "%ENV%"=="prod" if defined TYPE_OK (
echo [OK] 本番環境で csv または tsv ファイルを処理します
) else (
echo [NG] 条件を満たしません
)
10-2. OR の中に AND を含む((A AND B) OR (C AND D))
@echo off
:: 条件: (TYPE==csv AND SIZE>0) OR (TYPE==json AND SCHEMA==ok)
set "TYPE=csv"
set "SIZE=1024"
set "SCHEMA=ok"
set "VALID="
:: ケース1: csv かつ サイズ > 0
if /i "%TYPE%"=="csv" if %SIZE% GTR 0 set "VALID=1"
:: ケース2: json かつ スキーマOK
if /i "%TYPE%"=="json" if "%SCHEMA%"=="ok" set "VALID=1"
if defined VALID (
echo [OK] 処理を開始します
) else (
echo [NG] 入力データが有効ではありません
)
11. NOT条件のORとド・モルガンの法則
「A でない または B でない」は、ド・モルガンの法則(NOT(A AND B) = NOT A OR NOT B)を使って書けます。「どちらかが不成立なら全体として偽」というパターンで使われます。
@echo off
:: ド・モルガン: NOT(A AND B) = NOT A OR NOT B
:: 例: STATUS が active でない OR ROLE が admin でない → アクセス拒否
set "STATUS=active"
set "ROLE=user"
:: フラグ方式で OR 判定
set "DENY="
if not "%STATUS%"=="active" set "DENY=1"
if not "%ROLE%"=="admin" set "DENY=1"
if defined DENY (
echo [DENY] アクセス拒否: STATUS=%STATUS%, ROLE=%ROLE%
exit /b 1
)
echo [ALLOW] アクセスを許可します
:: 同等の AND 版(こちらの方が直感的な場合も)
:: if "%STATUS%"=="active" if "%ROLE%"=="admin" (echo ALLOW) else (echo DENY)
12. 落とし穴5選と対策
落とし穴1:|| はIF条件式では使えない
:: NG: || はコマンド連結(前が失敗したら次を実行)であり、IF 条件式では使えない if "%A%"=="x" || "%B%"=="y" echo OK :: 構文エラーになる :: OK: フラグ変数方式を使う set "OR=" if "%A%"=="x" set "OR=1" if "%B%"=="y" set "OR=1" if defined OR echo OK
落とし穴2:else-if チェーンは最初に成立した条件しか実行されない
:: A=1 かつ B=2 の場合、Aの処理だけ実行されBの処理は実行されない
set "A=1" & set "B=2"
if "%A%"=="1" (
echo A が成立
) else if "%B%"=="2" (
echo B が成立 ← A が成立していたらここは実行されない
)
:: 「どれか1つが成立したら同じ処理」にはフラグ変数方式を使う
set "MATCH="
if "%A%"=="1" set "MATCH=1"
if "%B%"=="2" set "MATCH=1"
if defined MATCH echo A または B が成立
落とし穴3:変数が空のとき引用符なしで比較すると構文エラー
:: NG: VAR が空だと "if ==value" になって構文エラー if %VAR%==A set "OK=1" if %VAR%==B set "OK=1" :: OK: 引用符で保護するか IF DEFINED で先に確認 if "%VAR%"=="A" set "OK=1" if "%VAR%"=="B" set "OK=1"
変数展開が動かない原因と修正方法 も参照してください。
落とし穴4:ループ内でフラグを更新すると %変数% では読めない
:: NG: ループ内で set したフラグを %MATCH% で読むと古い値
for %%F in (*.log) do (
if %%~zF GTR 1000 set "MATCH=1"
if %MATCH%==1 echo 見つかった ← MATCH が空のまま判定される
)
:: OK: setlocal enabledelayedexpansion + !MATCH! を使う
setlocal enabledelayedexpansion
for %%F in (*.log) do (
if %%~zF GTR 1000 set "MATCH=1"
if defined MATCH echo 見つかった
)
落とし穴5:FINDSTR の OR 検索は /c: を複数指定する(スペース区切りは別の意味)
:: NG: スペース区切りは "ERROR WARN" という1つの文字列として検索される findstr "ERROR WARN" app.log :: OK: /c: を複数指定して OR 検索 findstr /c:"ERROR" /c:"WARN" app.log :: OK: | で区切ることでも OR 検索できる(正規表現モード) findstr /r "ERROR\|WARN\|CRITICAL" app.log
13. 実践例3本
実践例1:入力バリデーション(複数の拡張子・値を OR で受け付ける)
@echo off
setlocal
set "FILE=%~1"
set "MODE=%~2"
:: ── 引数チェック ──
if "%FILE%"=="" (
echo 使い方: %~nx0 ^<ファイル^> ^<モード: fast^|safe^|dry^>
exit /b 1
)
:: ── 拡張子バリデーション(OR: .csv .tsv .txt のどれか)──
set "EXT_OK="
if /i "%~x1"==".csv" set "EXT_OK=1"
if /i "%~x1"==".tsv" set "EXT_OK=1"
if /i "%~x1"==".txt" set "EXT_OK=1"
if not defined EXT_OK (
echo [ERROR] 対応拡張子: .csv .tsv .txt (指定: %~x1)
exit /b 1
)
:: ── モードバリデーション(OR: fast safe dry のどれか)──
set "MODE_OK="
if /i "%MODE%"=="fast" set "MODE_OK=1"
if /i "%MODE%"=="safe" set "MODE_OK=1"
if /i "%MODE%"=="dry" set "MODE_OK=1"
if not defined MODE_OK (
echo [ERROR] モード: fast / safe / dry のいずれかを指定してください
exit /b 1
)
:: ── ファイル存在確認 ──
if not exist "%FILE%" (
echo [ERROR] ファイルが見つかりません: %FILE%
exit /b 1
)
echo [OK] %FILE% を %MODE% モードで処理します
実践例2:ログ異常検知スクリプト(OR条件による複数キーワード監視)
@echo off
setlocal enabledelayedexpansion
set "LOG_DIR=C:\work\logs"
set "ALERT_COUNT=0"
for %%F in ("%LOG_DIR%\*.log") do (
:: ERROR・CRITICAL・FATAL のどれかを含むファイルを検索(OR)
findstr /i /c:"ERROR" /c:"CRITICAL" /c:"FATAL" "%%F" >nul 2>&1
if not errorlevel 1 (
set /a ALERT_COUNT+=1
echo [ALERT] %%~nxF に異常キーワードが検出されました
findstr /i /c:"ERROR" /c:"CRITICAL" /c:"FATAL" "%%F" | findstr /n ".*"
)
)
if !ALERT_COUNT! GTR 0 (
echo ===== 計 !ALERT_COUNT! 件のログに異常を検出しました =====
exit /b 1
) else (
echo [OK] 全ログに異常なし
)
実践例3:デプロイ前チェック(AND/OR 混在のバリデーション)
「本番環境 かつ(承認フラグあり または 強制フラグあり)」という複合条件のデプロイガードです。
@echo off
setlocal
set "ENV=%~1" :: prod / stg / dev
set "APPROVED=%~2" :: yes / no
set "FORCE=%~3" :: force (任意)
:: ── OR: 承認済み または 強制フラグあり ──
set "CAN_DEPLOY="
if /i "%APPROVED%"=="yes" set "CAN_DEPLOY=1"
if /i "%FORCE%"=="force" set "CAN_DEPLOY=1"
:: ── AND: 本番環境 かつ デプロイ可能 ──
if /i "%ENV%"=="prod" (
if not defined CAN_DEPLOY (
echo [BLOCKED] 本番デプロイには承認が必要です
echo 承認済みデプロイ: %~nx0 prod yes
echo 強制デプロイ: %~nx0 prod no force
exit /b 1
)
echo [WARN] 本番環境へのデプロイを実行します。3秒後に開始します...
timeout /t 3 /nobreak >nul
) else (
echo [INFO] %ENV% 環境にデプロイします
)
echo [START] デプロイを開始します(ENV=%ENV%)
:: xcopy などのデプロイ処理をここに記述
echo [DONE] デプロイ完了
14. まとめ:OR条件パターン早見表
| パターン | 構文 | 用途・注意点 |
|---|---|---|
| フラグ変数OR | if 条件 set "F=1" → if defined F |
最も汎用的・AND混在可能 |
| else-if チェーン | if ... ) else if ... ) else ... |
条件ごとに処理が違うとき |
| 数値OR | 各値ごとに if %N% EQU x set "F=1" |
範囲外チェックにも使う |
| 文字列OR | 各候補ごとに if /i "%S%"=="x" set "F=1" |
/iで大小無視可 |
| EXIST OR | 各ファイルごとに if exist "f" set "F=1" |
どれか1つ存在すればOK |
| ERRORLEVEL OR | 各コマンド後に if not %ERR% EQU 0 set "F=1" |
どれかが失敗したら検出 |
| FINDSTR OR | findstr /c:"A" /c:"B" |
ファイル内容の複数キーワード検索 |
| 遅延展開OR | ループ内で set "F=1" → ループ後に if defined F |
FOR内の変数更新に必須 |
FAQ
|| 演算子は使えますか?|| はコマンドの連結(前のコマンドが失敗したら次を実行)には使えますが、if 文の条件式では使えません。IF 文の OR 条件はフラグ変数方式で実現します。%変数% で参照すると古い値になります。setlocal enabledelayedexpansion を宣言して !変数! で参照するか、ループの外で if defined MATCH で判定してください(→ 9節)。findstr /c:"キーワード1" /c:"キーワード2" のように /c: を複数指定します。正規表現モード(/r)では findstr /r "A\|B" のように \| で区切ることもできます。スペース区切りは「スペースを含む文字列」として1つの検索語になるため使えません。if not "%A%"=="x" set "F=1"、if not "%B%"=="y" set "F=1" のように書きます(→ 11節)。
