【bat】IF NOT EXISTでフォルダが存在しない場合のみ作成する方法完全ガイド|mkdir・階層一括・日付フォルダ・エラー処理・実践例まで徹底解説

【bat】バッチファイルでフォルダが存在しない場合のみ作成する方法 bat

バッチファイルでファイルのコピーやログ出力を行う前に、「保存先フォルダがなければ作っておきたい」という場面は非常によくあります。フォルダが存在しない状態でファイル操作を行うとエラーになるため、IF NOT EXIST + mkdir による事前確認と作成は、実務バッチの最頻出パターンのひとつです。この記事では、基本構文から始まり、末尾バックスラッシュと NUL の使い分け・複数フォルダの一括作成・階層フォルダの一括作成・日付付きフォルダの自動生成・エラー処理まで、実践例3本とともに体系的に解説します。

この記事でわかること

  • IF NOT EXIST + mkdir によるフォルダ存在確認と作成の基本パターン
  • フォルダ確認に使う末尾バックスラッシュ\NUL の違いと使い分け
  • 複数フォルダをまとめて作成するパターン(フラグ変数活用)
  • 深い階層フォルダを mkdir 1回で一括作成する方法
  • 日付付きフォルダを動的に自動生成するパターン
  • %~dp0 でスクリプト自身の場所を基準にフォルダを作成する方法
  • エラー処理と ERRORLEVEL の確認方法
  • 実践例3本(処理前準備・日次ログフォルダ・バックアップ構成一括作成)
スポンサーリンク

1. IF NOT EXIST + mkdir の基本構文

バッチファイルでフォルダを「存在しない場合のみ作成」するには、IF NOT EXIST で存在を確認してから mkdir を実行します。この組み合わせは、バッチ処理の前処理として最もよく使われるパターンです。

@echo off

set "TARGET=C:\work\output"

:: フォルダが存在しない場合のみ作成する(基本形)
if not exist "%TARGET%\" (
    mkdir "%TARGET%"
    echo フォルダを作成しました: %TARGET%
) else (
    echo フォルダは既に存在します: %TARGET%
)
pause

上記コードのポイントは2つです。まず、パス末尾に \(バックスラッシュ) を付けることで、フォルダとして存在するかを確認します(同名ファイルとの誤検知を防ぐ)。次に mkdir をダブルクォートで囲み、スペースを含むパスでも正しく動作するようにします。フォルダ存在確認の詳細は IF EXISTでの存在確認完全ガイド、mkdir の詳しい使い方は フォルダを作成する方法完全ガイドも参照してください。

1-1. else なしの簡潔な書き方(実務で最もよく使う形)

実際の現場では「存在しなければ作る」だけで十分なことがほとんどです。else を省いたシンプルな1行形式が最も多く使われます。

@echo off

:: ─── 最もよく使うシンプルな形 ─────────────────────────────
if not exist "C:\work\output\"  mkdir "C:\work\output"
if not exist "C:\work\logs\"   mkdir "C:\work\logs"
if not exist "C:\work\backup\" mkdir "C:\work\backup"

echo フォルダ準備完了
pause
mkdir は既存フォルダがあってもエラーにならないが IF NOT EXIST が推奨の理由
実は mkdir "C:\work\output" をそのまま実行しても、フォルダが存在する場合は「サブディレクトリまたはファイルが既に存在します」というエラーメッセージが表示され、ERRORLEVEL が 1 になります。バッチの処理に影響しないケースもありますが、if %ERRORLEVEL% neq 0 でエラーチェックをしている場合に誤検知します。IF NOT EXIST で確認してから mkdir することで、ERRORLEVEL を汚染せずクリーンに作成できます。

2. フォルダ確認:末尾バックスラッシュ(\)と \NUL の使い分け

IF NOT EXIST でフォルダを確認するとき、パスの末尾に何を付けるかで動作が異なります。2種類の方法を理解して使い分けましょう。

書き方 動作 同名ファイルとの区別 推奨度
IF NOT EXIST "path\" 末尾 \ でフォルダとして存在確認 △ 同名ファイルがあれば誤検知の可能性 ◎ 一般的・現場標準
IF NOT EXIST "path\NUL" NUL デバイスでフォルダのみ確認 ○ フォルダのみを確実に検出 ○ 特殊用途に使用
IF NOT EXIST "path"(末尾なし) ファイルかフォルダか区別しない ✗ 同名ファイルがあれば作成しない ✗ フォルダ確認には使わない
@echo off

:: ─── 末尾 \ を使う方法(最も一般的) ────────────────────
if not exist "C:\work\backup\" (
    mkdir "C:\work\backup"
    echo 作成しました
)

:: ─── \NUL を使う方法(フォルダのみを確実に検出) ────────
if not exist "C:\work\backup\NUL" (
    mkdir "C:\work\backup"
    echo 作成しました
)
どちらを使えばよいか
ほとんどの現場では末尾 \ を使う方法が標準です。同名のファイルとフォルダが共存するような特殊な状況は通常ありません。可読性が高く記述も簡単な末尾 \ 方式を一貫して使うことを推奨します。\NUL はデバイスファイルを利用した方法で、「絶対にフォルダのみを確認したい」という要件がある場合に限って使います。

3. 複数フォルダをまとめて作成する

3-1. 単純に並べる方法(推奨)

スクリプト実行前に複数のフォルダを準備したい場合は、IF NOT EXIST + mkdir を必要な数だけ並べるのが最もシンプルです。

@echo off

:: ─── バッチ処理に必要なフォルダを一括作成 ──────────────────
if not exist "C:\work\input\"   mkdir "C:\work\input"
if not exist "C:\work\output\"  mkdir "C:\work\output"
if not exist "C:\work\logs\"    mkdir "C:\work\logs"
if not exist "C:\work\backup\"  mkdir "C:\work\backup"
if not exist "C:\work\archive\" mkdir "C:\work\archive"

echo [OK] フォルダ準備完了
echo 処理を開始します
pause

3-2. 変数リストで管理する方法

作成するフォルダをリストとして管理したい場合は、for ループを使うとスッキリ書けます。フォルダの追加・削除が変数1か所の変更で済むため、保守性が高まります。

@echo off
setlocal enabledelayedexpansion

:: ─── 作成するフォルダのリストを定義 ────────────────────────
set "BASE=C:\work"
set "DIRS=input output logs backup archive temp"

for %%D in (%DIRS%) do (
    if not exist "%BASE%\%%D\" (
        mkdir "%BASE%\%%D"
        echo [作成] %BASE%\%%D
    ) else (
        echo [既存] %BASE%\%%D
    )
)

echo [OK] フォルダ準備完了
pause

4. 深い階層のフォルダを一括作成する

Windowsの mkdirmd)は、中間ディレクトリが存在しなくても、パスを一括で作成します。Linux の mkdir -p と同様の動作を、オプションなしで実現できます。

@echo off

:: ─── 中間フォルダがなくても一括で作成される ──────────────
:: C:\work も projects も 2025 も存在しなくてもまとめて作成される
if not exist "C:\work\projects\2025\reports\" (
    mkdir "C:\work\projects\2025\reports"
    echo 階層フォルダを作成しました: C:\work\projects\2025\reports
)

:: ─── 複数の深い階層を一括作成 ──────────────────────────────
for %%D in (
    "C:\data\2025\01\input"
    "C:\data\2025\01\output"
    "C:\data\2025\01\logs"
) do (
    if not exist %%D\ mkdir %%D
)

echo 階層フォルダ作成完了
pause
Windows の mkdir は -p オプション不要
Linux/macOS では深い階層を作るときに mkdir -p /a/b/c のように -p オプションが必要ですが、Windowsの mkdir は常にパス全体を一括作成するため、オプション不要です。mkdir "C:\a\b\c"abc も一度に作れます。

5. 日付付きフォルダを動的に自動生成する

ログやバックアップを日付ごとに保存したい場合は、%DATE% からフォルダ名を組み立てて動的に作成するパターンが便利です。日付をファイル名に使う方法も合わせて参照してください。

@echo off

:: ─── 今日の日付を YYYYMMDD 形式で取得 ─────────────────────
:: %DATE% が "2025/04/14" 形式の場合
set "YMD=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%"

:: ─── 日付別フォルダを作成 ──────────────────────────────────
set "LOG_DIR=C:\logs\%YMD%"
set "BACKUP_DIR=C:\backup\%YMD%"

if not exist "%LOG_DIR%\"    mkdir "%LOG_DIR%"
if not exist "%BACKUP_DIR%\" mkdir "%BACKUP_DIR%"

echo [OK] 本日のフォルダ作成完了
echo   ログ  : %LOG_DIR%
echo   バックアップ: %BACKUP_DIR%
pause

5-1. 年月階層フォルダを動的作成する

年月で階層を分けてファイルを管理したい場合は、年・月ごとのフォルダを組み合わせて作成します。

@echo off

set "YEAR=%DATE:~0,4%"
set "MONTH=%DATE:~5,2%"
set "DAY=%DATE:~8,2%"

:: ─── 年/月/日 の階層フォルダを一括作成 ────────────────────
set "ARCHIVE=C:\archive\%YEAR%\%MONTH%\%DAY%"

if not exist "%ARCHIVE%\" (
    mkdir "%ARCHIVE%"
    echo [作成] %ARCHIVE%
) else (
    echo [既存] %ARCHIVE%
)

echo 保存先: %ARCHIVE%
pause

6. %~dp0 でスクリプトと同じ場所にフォルダを作成する

%~dp0 はバッチファイル自身が置かれているフォルダのパスです。絶対パスをハードコードせず、バッチファイルの場所を基準にフォルダを作成すると、バッチをどの場所に置いても正しく動作します。特にスクリプトセットを複数の環境に展開するときに有効です。

@echo off

:: %~dp0 はこのバッチファイルがある場所(末尾にバックスラッシュ付き)
:: 例: バッチが C:\tools\myscript.bat にあれば %~dp0 は C:\tools\ になる

:: ─── バッチと同じフォルダにサブフォルダを作成 ──────────────
if not exist "%~dp0logs\"    mkdir "%~dp0logs"
if not exist "%~dp0output\"  mkdir "%~dp0output"
if not exist "%~dp0backup\"  mkdir "%~dp0backup"

echo [OK] フォルダ作成完了
echo バッチの場所: %~dp0
pause
%~dp0 はすでに末尾にバックスラッシュが付いている
%~dp0 の値は C:\tools\ のように末尾に \ が付いています。そのため %~dp0\logs と書くと C:\tools\\logs になってしまいます。%~dp0logs(バックスラッシュなし)と書くのが正しい形です。IF NOT EXIST の確認時は "%~dp0logs\" のように末尾に \ を追加します。

7. エラー処理:ERRORLEVEL の確認と対処

mkdir が失敗した場合(権限不足・ドライブが存在しないなど)、ERRORLEVEL が 1 になります。重要な処理の前処理として使う場合は、エラー時に処理を中断する制御を追加しましょう。

@echo off

set "TARGET=C:\work\output"

:: ─── フォルダ作成後にERRORLEVELを確認する ─────────────────
if not exist "%TARGET%\" (
    mkdir "%TARGET%"
    if %ERRORLEVEL% neq 0 (
        echo [ERROR] フォルダの作成に失敗しました: %TARGET%
        echo 権限不足またはドライブが存在しない可能性があります
        exit /b 1
    )
    echo [OK] フォルダを作成しました: %TARGET%
)

echo 処理を開始します
pause

7-1. 複数フォルダ作成時のエラー処理

@echo off
setlocal enabledelayedexpansion

set "BASE=C:\work"
set "DIRS=input output logs backup"
set /a "ERR=0"

for %%D in (%DIRS%) do (
    if not exist "%BASE%\%%D\" (
        mkdir "%BASE%\%%D"
        if !ERRORLEVEL! neq 0 (
            echo [ERROR] 作成失敗: %BASE%\%%D
            set /a "ERR+=1"
        ) else (
            echo [OK] 作成: %BASE%\%%D
        )
    ) else (
        echo [既存] %BASE%\%%D
    )
)

if !ERR! gtr 0 (
    echo [ERROR] %ERR% 件のフォルダ作成に失敗しました
    exit /b 1
)

echo [OK] 全フォルダ準備完了
pause

8. ネットワークドライブや UNC パスへの対応

ネットワークドライブや UNC パス(\\server\share\...)にフォルダを作成する場合も基本は同じです。ただし、ネットワーク接続が切れているとタイムアウトが発生するため、接続確認を先に行うことを推奨します。

@echo off

:: ─── UNCパスでのフォルダ作成 ───────────────────────────────
set "UNC_TARGET=\\fileserver\share\backup\2025"

:: ─── 接続確認(ping 1回) ──────────────────────────────────
ping -n 1 -w 3000 fileserver >nul 2>&1
if %ERRORLEVEL% neq 0 (
    echo [ERROR] fileserver に到達できません
    exit /b 1
)

:: ─── UNCパスにフォルダ作成 ──────────────────────────────────
if not exist "%UNC_TARGET%\" (
    mkdir "%UNC_TARGET%"
    echo [OK] 作成: %UNC_TARGET%
)
pause
ネットワークパスは末尾バックスラッシュの扱いに注意
UNCパスの場合、if not exist "\\server\share\" は共有フォルダ自体の存在確認になります。共有フォルダ配下のサブフォルダを確認する場合はif not exist "\\server\share\subfolder\" と明示的にパスを指定してください。また、タスクスケジューラなどシステムアカウントで実行するバッチでは、事前に net use でドライブをマウントする必要がある場合があります。

9. 実践例3本

実践例1:処理実行前に必須フォルダをまとめて準備する

バッチファイルの処理開始前に、必要なフォルダが揃っているかを確認して自動作成する前処理テンプレートです。どのバッチにも組み込める汎用パターンです。

@echo off

:: ─── バッチと同じフォルダを基準にフォルダを作成する ────────
set /a "PREPARE_ERR=0"

:make_dir
    if not exist "%~1\" (
        mkdir "%~1"
        if errorlevel 1 (
            echo [ERROR] 作成失敗: %~1
            set /a "PREPARE_ERR+=1"
        ) else (
            echo [作成] %~1
        )
    ) else (
        echo [既存] %~1
    )
    goto :eof

:: ─── メイン処理 ─────────────────────────────────────────────
call :make_dir "%~dp0input"
call :make_dir "%~dp0output"
call :make_dir "%~dp0logs"
call :make_dir "%~dp0backup"

if %PREPARE_ERR% gtr 0 (
    echo [ERROR] フォルダ準備に失敗しました。処理を中止します
    exit /b 1
)

echo [OK] フォルダ準備完了。処理を開始します
echo.

:: ─── ここに実際の処理を記述 ────────────────────────────────
echo 処理中...
pause

実践例2:日次ログフォルダを自動作成してログを保存する

毎日の処理ログを日付別フォルダに自動保存するパターンです。ログ出力の詳しい方法と組み合わせています。

@echo off
setlocal enabledelayedexpansion

:: ─── 今日の日付でフォルダを作成 ────────────────────────────
set "YMD=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%"
set "LOG_DIR=%~dp0logs\%YMD%"
set "LOG_FILE=%LOG_DIR%\process_%YMD%.txt"

if not exist "%LOG_DIR%\" (
    mkdir "%LOG_DIR%"
    echo [%DATE% %TIME%] ログフォルダを作成しました: %LOG_DIR%
)

:: ─── ログ出力開始 ───────────────────────────────────────────
echo [%DATE% %TIME%] ========== 処理開始 ========== >> "%LOG_FILE%"
echo [%DATE% %TIME%] ログフォルダ: %LOG_DIR% >> "%LOG_FILE%"

:: ─── メイン処理(省略) ─────────────────────────────────────
echo [%DATE% %TIME%] 処理を実行中... >> "%LOG_FILE%"

echo [%DATE% %TIME%] ========== 処理完了 ========== >> "%LOG_FILE%"
echo ログ出力先: %LOG_FILE%
pause

実践例3:バックアップ先フォルダ構成を一括作成してファイルをコピーする

複数の送信元フォルダに対応したバックアップ構成を一括作成し、ファイルをコピーする実践例です。ファイルをコピーする方法と組み合わせています。

@echo off
setlocal enabledelayedexpansion

set "YMD=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%"
set "BACKUP_ROOT=C:\backup\%YMD%"

:: ─── バックアップ対象リスト(元フォルダ:バックアップ先サブ名) ─
set "SRC1=C:\work\projects"  & set "DST1=projects"
set "SRC2=C:\work\documents" & set "DST2=documents"
set "SRC3=C:\work\configs"   & set "DST3=configs"

:: ─── バックアップ先フォルダを一括作成 ──────────────────────
echo バックアップ先フォルダを準備中: %BACKUP_ROOT%

for %%N in (1 2 3) do (
    set "DSTDIR=%BACKUP_ROOT%\!DST%%N!"
    if not exist "!DSTDIR!\" (
        mkdir "!DSTDIR!"
        echo [作成] !DSTDIR!
    )
)

:: ─── ファイルをコピー ───────────────────────────────────────
for %%N in (1 2 3) do (
    set "SRCDIR=!SRC%%N!"
    set "DSTDIR=%BACKUP_ROOT%\!DST%%N!"
    if exist "!SRCDIR!\" (
        xcopy "!SRCDIR!" "!DSTDIR!" /e /y /q
        echo [コピー完了] !SRCDIR! → !DSTDIR!
    ) else (
        echo [スキップ] 元フォルダなし: !SRCDIR!
    )
)

echo バックアップ完了: %BACKUP_ROOT%
pause

10. まとめ:IF NOT EXIST + mkdir チートシート

やりたいこと 記述例 備考
基本:存在しなければ作成 if not exist "path\" mkdir "path" 末尾 \ でフォルダ確認
既存確認あり・ELSE付き if not exist "path\" ( mkdir "path" ) else ( echo 既存 ) ログ出力などに
NULで確実にフォルダのみ確認 if not exist "path\NUL" mkdir "path" 同名ファイル誤検知ゼロ
複数フォルダ一括 if not exist "a\" mkdir "a" を必要数並べる 最もシンプル
forループで一括作成 for %%D in (a b c) do if not exist "base\%%D\" mkdir "base\%%D" リスト管理に便利
深い階層を一括 if not exist "a\b\c\" mkdir "a\b\c" Windows mkdirはオプション不要
日付フォルダ自動作成 set "YMD=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%"
if not exist "logs\%YMD%\" mkdir "logs\%YMD%"
日次ログ・バックアップに
スクリプト基準パス if not exist "%~dp0logs\" mkdir "%~dp0logs" %~dp0は末尾\付き
エラー処理付き mkdir "path" && echo OK || echo ERROR if ERRORLEVEL neq 0 でも可
UNCパス対応 if not exist "\\server\share\path\" mkdir "\\server\share\path" 接続確認もセットで

FAQ

QIF NOT EXIST なしで mkdir を実行しても動作しますか?

A動作しますが、フォルダが既に存在する場合に 「サブディレクトリまたはファイルが既に存在します」というエラーメッセージが表示され、ERRORLEVEL が 1 になります。if %ERRORLEVEL% neq 0 でエラーチェックしている場合は誤検知になるため、IF NOT EXIST で確認してから実行することを推奨します。

Qmkdir と md はどちらを使えばよいですか?

Amkdirmd はまったく同じコマンドです(mdは別名)。バッチファイルではどちらを使っても動作します。可読性の点から、意味が明確な mkdir(make directory)を使うことを推奨します。

Qフォルダ名にスペースが含まれる場合はどう書けばよいですか?

Aパスをダブルクォートで囲んでください。if not exist "C:\My Folder\"mkdir "C:\My Folder" のように、IF NOT EXIST の確認時も mkdir の実行時も両方クォートが必要です。変数に格納する場合は set "TARGET=C:\My Folder" とセットしておき、"%TARGET%\" のように展開時もクォートで囲みます。

Qフォルダを作成した後すぐにそのフォルダにファイルを保存できますか?

Aはい、mkdir の直後にそのフォルダへの操作(copyecho >>など)を行えます。ただしネットワークドライブの場合は、作成直後にアクセスするとタイムラグで失敗することが稀にあります。ローカルドライブでは問題ありません。

Q作成したフォルダを後から削除するにはどうすれば良いですか?

A空のフォルダは rmdir "フォルダパス"、フォルダとその中身ごと削除する場合は rmdir /s /q "フォルダパス" を使います。フォルダを削除する方法の完全ガイドで詳しく解説しています。

Qタスクスケジューラで実行するバッチでフォルダ作成に失敗します。

A主な原因は権限不足です。タスクスケジューラのデフォルトは制限アカウントで実行されるため、C:\ 直下などへの書き込み権限がない場合があります。対処法は2つです。①タスクスケジューラの設定で「最上位の特権で実行する」にチェックを入れる、②ユーザーフォルダ(%USERPROFILE%)や %TEMP% など書き込み権限がある場所に変更する。