バッチファイルでファイルを操作する前に「そのファイルが存在するか確認したい」「フォルダがなければ作りたい」といった場面は頻繁にあります。IF EXIST はバッチファイルでファイル・フォルダの存在を確認する最もシンプルな方法で、実務バッチの基本構文のひとつです。この記事では IF EXIST の基本から、IF NOT EXIST・ELSE・ネスト・ワイルドカード・スペースを含むパスの注意点・よく使う実践パターンまでを体系的に解説します。
IF EXISTの基本構文とファイル・フォルダ両方の確認方法- フォルダ確認の 末尾バックスラッシュ vs NUL の違いと使い分け
- スペースを含むパスでのダブルクォート対応(よくあるハマりポイント)
IF NOT EXIST・ELSE・ネストを使った条件分岐パターン- ワイルドカード・ファイルサイズ0バイト判定・ネットワークドライブへの対応
- 実践例3本(フォルダ自動作成・必須ファイル一括チェック・ロックファイル二重起動防止)
1. IF EXIST の基本構文
IF EXIST の基本構文は以下のとおりです。パスに一致するファイルまたはフォルダが存在すれば、ブロック内のコマンドを実行します。
:: ファイルまたはフォルダが存在するとき実行
IF EXIST パス コマンド
:: 複数行のコマンドをまとめる場合はブロック () で囲む
IF EXIST パス (
コマンド1
コマンド2
)
:: 存在しないとき実行(NOT を付ける)
IF NOT EXIST パス コマンド
:: 存在する/しないで分岐(ELSE)
IF EXIST パス (
コマンドA :: 存在するとき
) ELSE (
コマンドB :: 存在しないとき
)
1-1. ファイルの存在確認
@echo off
IF EXIST "C:\work\data.txt" (
echo ファイルが存在します
) ELSE (
echo ファイルが存在しません
)
pause
1-2. フォルダの存在確認(末尾バックスラッシュ vs NUL)
フォルダの存在確認にはパスの末尾に \(バックスラッシュ) または \NUL を付けます。これを付けないと、同名のファイルを誤検知することがあります。
@echo off
:: 方法1: 末尾に \ を付ける(簡潔・一般的)
IF EXIST "C:\work\backup\" (
echo フォルダが存在します
)
:: 方法2: \NUL を付ける(より確実・同名ファイルを完全に除外)
IF EXIST "C:\work\backup\NUL" (
echo フォルダが存在します
)
| 確認対象 | 書き方 | 注意点 |
|---|---|---|
| ファイル | IF EXIST "C:\work\data.txt" |
パスをそのまま指定 |
| フォルダ(一般的) | IF EXIST "C:\work\backup\" |
末尾に \ を付ける |
| フォルダ(確実) | IF EXIST "C:\work\backup\NUL" |
NUL でフォルダのみを検出 |
| ワイルドカード | IF EXIST "C:\work\*.csv" |
1つでも一致すれば真 |
通常の用途では末尾
\ で十分です。\NUL はデバイスファイルへの参照を使ってフォルダ存在を確認するため、同名ファイルが絶対に誤検知されない保証が必要な場合に使います。多くの現場では \ 方式が一般的です。2. IF NOT EXIST:存在しない場合に処理する
IF NOT EXIST はファイル・フォルダが存在しないときに処理を実行します。「なければ作る」「なければエラーで終了する」といった処理に使います。フォルダを作成する方法と組み合わせると、実行前の準備処理として活用できます。
@echo off
:: 設定ファイルが存在しない場合はエラー終了
IF NOT EXIST "config.ini" (
echo エラー: config.ini が見つかりません
exit /b 1
)
:: 出力フォルダが存在しない場合は自動作成
IF NOT EXIST "C:\work\output\" (
mkdir "C:\work\output"
echo output フォルダを作成しました
)
echo 処理を開始します
pause
フォルダが存在しない場合のみ作成するは、バッチ処理の前処理として非常によく使われます。
mkdir は既存フォルダを上書きしませんが、IF NOT EXIST で確認してから作成するほうが意図が明確になります。3. スペースを含むパスはダブルクォートで囲む
C:\Program Files のようにパスにスペースが含まれる場合、ダブルクォートで囲まないと構文エラーになります。これは IF EXIST に限らず、バッチ全般でよくあるハマりポイントです。
@echo off
:: ❌ スペースがあるとエラー("Files" 以降が別の引数扱い)
IF EXIST C:\Program Files\app.exe echo NG
:: ✅ ダブルクォートで囲む
IF EXIST "C:\Program Files\app.exe" (
echo アプリが存在します
)
:: ✅ 変数を使う場合もダブルクォートで囲む
set "TARGET=C:\Program Files\app.exe"
IF EXIST "%TARGET%" (
echo 存在します
)
pause
スペースがない場合でも、ダブルクォートを付けても問題ありません。特に変数で動的にパスを組み立てるときは、スペースが入る可能性を考慮して 常にダブルクォートで囲む のが安全です。
IF EXIST "%~dp0\data.csv" のように %~dp0(スクリプトと同じフォルダ)にも適用しましょう。4. ELSE との組み合わせとネスト
4-1. ELSE の正しい書き方
IF EXIST ... ELSE ... で存在する場合・しない場合の処理を分岐できます。ELSE は必ず ) と同じ行に書く必要があります。別行に書くと構文エラーになります。
@echo off
:: ✅ 正しい書き方 — ) ELSE ( を同じ行に書く
IF EXIST "input.csv" (
echo input.csv を処理します
) ELSE (
echo エラー: input.csv が見つかりません
exit /b 1
)
:: ❌ 間違い — ELSE を別行に書くと構文エラー
IF EXIST "input.csv" (
echo 存在する
)
ELSE ( :: ← ここでエラー
echo 存在しない
)
pause
4-2. IF EXIST のネスト(複数条件を組み合わせる)
複数のファイルやフォルダを組み合わせた条件分岐には、IF EXIST をネスト(入れ子)にして記述します。
@echo off
:: config.ini と input.csv の両方が存在する場合のみ処理
IF EXIST "config.ini" (
IF EXIST "input.csv" (
echo 両方のファイルが揃っています。処理を開始します
) ELSE (
echo エラー: input.csv が見つかりません
exit /b 1
)
) ELSE (
echo エラー: config.ini が見つかりません
exit /b 1
)
pause
4-3. フラグ変数で複数チェックをまとめる(ネストの代替)
ネストが深くなると読みにくくなります。フラグ変数を使って複数チェックを平坦に記述する方法も有効です。フラグ変数の使い方を参照してください。
@echo off
set "ERR=0"
IF NOT EXIST "config.ini" ( echo 不足: config.ini & set "ERR=1" )
IF NOT EXIST "input.csv" ( echo 不足: input.csv & set "ERR=1" )
IF NOT EXIST "template.xlsx" ( echo 不足: template.xlsx & set "ERR=1" )
if "%ERR%"=="1" (
echo 必須ファイルが不足しています。処理を中止します
exit /b 1
)
echo 全ファイル確認OK。処理を開始します
pause
5. ワイルドカードで複数ファイルをまとめて確認する
IF EXIST ではパスに *(任意の文字列)と ?(任意の1文字)のワイルドカードが使えます。「1つでも一致するファイルがあれば真」という判定になります。
@echo off
:: *.csv が1つでも存在するか確認
IF EXIST "C:\work\*.csv" (
echo CSVファイルが見つかりました
) ELSE (
echo CSVファイルがありません
)
:: 今日の日付のログファイルが存在するか確認
for /f "tokens=1-3 delims=/ " %%a in ("%DATE%") do set "TODAY=%%a%%b%%c"
IF EXIST "C:\logs\log_%TODAY%*.txt" (
echo 本日のログが存在します
)
:: report_??.xlsx(report_01.xlsx など2文字番号)の確認
IF EXIST "C:\work\report_??.xlsx" (
echo レポートファイルが存在します
)
pause
IF EXIST "C:\work\*.csv" は C:\work\ 直下のみを検索します。サブフォルダを含めて検索したい場合は for /r を使ったファイル一覧取得を組み合わせてください。6. ファイルサイズ・更新日時を組み合わせた高度な確認
6-1. ファイルサイズが0バイトかどうかを判定する
IF EXIST は存在確認のみで、サイズの判定はできません。0バイトのファイルも「存在する」と判定されます。サイズが0バイトかどうかは FOR 文の修飾子 %%~z で判定します。
@echo off
:: まず存在確認してから、サイズを確認
IF EXIST "C:\work\data.csv" (
for %%f in ("C:\work\data.csv") do (
if %%~zf==0 (
echo ファイルは存在しますが空です(0バイト)
) else (
echo ファイルが存在します(%%~zf バイト)
)
)
) ELSE (
echo ファイルが存在しません
)
pause
6-2. 更新日時と組み合わせてファイルの鮮度を確認する
存在確認と更新日時チェックを組み合わせると、「今日作成されたファイルだけ処理する」といった制御ができます。ファイルの更新日時を取得する方法も参照してください。
@echo off
setlocal enabledelayedexpansion
:: 今日の日付を取得
for /f "tokens=1-3 delims=/ " %%a in ("%DATE%") do set "TODAY=%%a/%%b/%%c"
:: ファイルが存在するかつ今日の更新か確認
IF EXIST "C:\work\data.csv" (
for %%f in ("C:\work\data.csv") do (
set "FDATE=%%~tf"
:: %%~tf は "YYYY/MM/DD HH:MM" 形式
set "FDATE=!FDATE:~0,10!"
if "!FDATE!"=="%TODAY%" (
echo [OK] 今日更新されたファイルです
) else (
echo [注意] ファイルは古い可能性があります(更新日: !FDATE!)
)
)
)
pause
7. よくある失敗例と対処法
| 症状 | 原因 | 対処法 |
|---|---|---|
| スペース入りパスで構文エラー | ダブルクォートなし | "パス" でダブルクォートを付ける |
| フォルダなのにファイルを誤検知 | 末尾の \ を付けていない |
"フォルダ\" または "フォルダ\NUL" を使う |
ELSE で構文エラー |
ELSE を ) と別行に書いている |
) ELSE ( を同じ行に書く |
| 変数パスで IF EXIST が効かない | 変数にスペースが含まれてクォートなし | IF EXIST "%変数%" と常にクォートで囲む |
| ワイルドカードで意図しないファイルを検知 | 別パターンのファイルが存在した | パターンをより具体的にするか FOR と組み合わせる |
| ネットワークパスでタイムアウトが長い | サーバーが切断されている状態で確認している | 事前に net use で接続確認してから IF EXIST を実行する |
8. 実践例3本
実践例1:バックアップフォルダを日付付きで自動作成する
処理実行前にバックアップ先フォルダが存在しなければ自動作成し、既存ファイルをバックアップしてから上書きする実践例です。日付をファイル名に使う方法と組み合わせています。
@echo off
setlocal enabledelayedexpansion
:: 日付を取得してバックアップフォルダ名に使う
for /f "tokens=1-3 delims=/ " %%a in ("%DATE%") do set "TODAY=%%a%%b%%c"
set "SRC=C:\work\result.csv"
set "BACKUP_DIR=C:\work\backup\%TODAY%"
:: ─── Step1: バックアップフォルダを確認・作成 ──────
IF NOT EXIST "%BACKUP_DIR%\" (
mkdir "%BACKUP_DIR%"
echo バックアップフォルダを作成: %BACKUP_DIR%
)
:: ─── Step2: 既存ファイルをバックアップに退避 ──────
IF EXIST "%SRC%" (
for /f "tokens=1-3 delims=: " %%a in ("%TIME: =0%") do set "NOW=%%a%%b%%c"
copy "%SRC%" "%BACKUP_DIR%\result_!NOW!.csv" >nul
echo 既存ファイルを退避: %BACKUP_DIR%\result_!NOW!.csv
)
:: ─── Step3: 新しいファイルを生成 ──────────────────
echo 処理日時,%TODAY% > "%SRC%"
echo result.csv を更新しました
pause
実践例2:処理実行前に必須ファイル・フォルダを一括チェックする
複数の必須ファイルやフォルダの存在を処理開始前にまとめて確認し、不足があればエラーメッセージを一覧表示してから中止するスクリプトです。設定ファイルが揃っているか確認する前処理として実務でよく使われます。
@echo off
set "ERR=0"
:: ─── 必須ファイルの存在チェック ────────────────────
echo [チェック] 必須ファイルを確認中...
IF NOT EXIST "config.ini" ( echo ✗ 不足: config.ini & set "ERR=1" )
IF NOT EXIST "input.csv" ( echo ✗ 不足: input.csv & set "ERR=1" )
IF NOT EXIST "template.xlsx" ( echo ✗ 不足: template.xlsx & set "ERR=1" )
:: ─── 必須フォルダの存在チェック ───────────────────
IF NOT EXIST "C:\work\logs\" ( echo ✗ 不足フォルダ: C:\work\logs & set "ERR=1" )
IF NOT EXIST "C:\work\output\" ( echo ✗ 不足フォルダ: C:\work\output & set "ERR=1" )
:: ─── チェック結果 ──────────────────────────────────
if "%ERR%"=="1" (
echo.
echo [エラー] 上記の不足ファイル/フォルダを確認してください
echo 処理を中止します
pause
exit /b 1
)
echo [OK] 全ファイル・フォルダ確認済み。処理を開始します
pause
実践例3:ロックファイルによる二重起動防止
バッチを同時に複数起動すると処理が競合することがあります。「ロックファイル」を使って二重起動を防ぐパターンです。フラグファイルを使った制御の応用例でもあります。
@echo off
set "LOCK=%~dp0running.lock"
:: ─── 二重起動チェック ──────────────────────────────
IF EXIST "%LOCK%" (
echo [二重起動防止] 既に実行中です。処理を終了します
echo ロックファイル: %LOCK%
pause
exit /b 1
)
:: ─── ロックファイルを作成して処理開始 ─────────────
echo %DATE% %TIME% > "%LOCK%"
echo [開始] ロックファイルを作成しました: %LOCK%
:: ─── メイン処理(ここに実際の処理を記述) ─────────
echo 処理を実行中...
ping -n 5 127.0.0.1 >nul
:: ─── 正常終了時にロックファイルを削除 ─────────────
IF EXIST "%LOCK%" del "%LOCK%"
echo [完了] 処理が終了しました
pause
注意: バッチが異常終了するとロックファイルが残ったままになります。次回起動時に二重起動と誤判定されるため、古いロックファイルを自動削除するロジックを追加するとより堅牢になります。
9. まとめ:IF EXIST チートシート
| やりたいこと | 記述例 | 備考 |
|---|---|---|
| ファイルの存在確認 | IF EXIST "C:\file.txt" ( 処理 ) |
基本形 |
| フォルダの存在確認(一般的) | IF EXIST "C:\folder\" ( 処理 ) |
末尾 \ を付ける |
| フォルダの存在確認(確実) | IF EXIST "C:\folder\NUL" ( 処理 ) |
同名ファイルの誤検知ゼロ |
| 存在しない場合の処理 | IF NOT EXIST "path" ( 処理 ) |
NOT を付けるだけ |
| 存在する/しないで分岐 | IF EXIST "path" ( 処理A ) ELSE ( 処理B ) |
ELSE は ) と同じ行 |
| フォルダがなければ作成 | IF NOT EXIST "folder\" mkdir "folder" |
最頻出パターン |
| 複数ファイル一括チェック | フラグ変数 ERR + 複数 IF NOT EXIST |
ネストを避けて可読性UP |
| ワイルドカードで確認 | IF EXIST "C:\work\*.csv" ( 処理 ) |
1つでも一致すれば真 |
| ファイルサイズが0バイト判定 | FOR %%f IN ("file") DO IF %%~zf==0 ... |
IF EXISTではサイズ判定不可 |
| ロックファイル二重起動防止 | IF EXIST "lock" ( exit ) ELSE ( echo x > "lock" ) |
終了時に lock を削除 |
FAQ
QIF EXIST でファイルサイズが0バイトかどうかも判定できますか?
AIF EXIST は存在確認のみで、サイズの判定はできません。0バイトのファイルも「存在する」と判定されます。サイズが0バイトかどうかは FOR %%f IN ("ファイル") DO IF %%~zf==0 ... のように %%~z(ファイルサイズ修飾子)を使って判定します。
Qネットワークドライブのファイル存在確認も IF EXIST でできますか?
Aできます。IF EXIST "\\server\share\file.txt" のように UNCパスをそのまま使えます。ただしネットワーク接続が切れている場合は、タイムアウトまでに時間がかかることがあります。事前に net use で接続確認するか、タイムアウト時間を考慮した設計を推奨します。
Qフォルダ確認で末尾 \ と \NUL はどちらを使うべきですか?
A一般的な用途では末尾 \ で十分です。\NUL は同名のファイルとフォルダが共存する可能性がある環境で使います。例えば backup というファイルと backup というフォルダが同時に存在する状況では \NUL のほうが正確です。ただしそのような状況は通常ありえないため、\ 方式が現場では一般的です。
QIF EXIST とディレクトリ属性 (/d) の違いは何ですか?
AIF EXIST はファイルもフォルダも区別せず「存在するか」を確認します。dir /ad コマンドと組み合わせると属性(隠しフォルダ・読み取り専用など)を考慮した確認もできますが、通常の存在確認には IF EXIST だけで十分です。隠しフォルダ(属性 h)も IF EXIST で正しく検出されます。
QIF EXIST と IF ERRORLEVEL はどちらを使うべきですか?
A用途が異なります。IF EXIST はファイル・フォルダの存在確認専用です。IF ERRORLEVEL は直前のコマンドの終了コード(成功/失敗)を判定するものです。ファイルの存在確認には必ず IF EXIST を使ってください。IF ERRORLEVEL 1 は「終了コードが1以上」を意味するため、ファイル確認には使えません。
Qバッチ実行後にロックファイルが残ってしまいます。
Aバッチが途中でエラー終了したり強制終了されると、ロックファイルの削除処理が実行されずに残ることがあります。対策として、スクリプト先頭でロックファイルの作成日時を確認し、古い(例えば24時間以上前の)ロックファイルは自動削除するロジックを追加する方法があります。または、forfiles /m running.lock /d -1 /c "cmd /c del @file" で1日以上前のロックファイルを削除するコードを冒頭に置く方法も有効です(/d -1 = 1日以上前のファイルを対象)。
