「古いログファイルを定期削除したい」「拡張子別に不要ファイルを一掃したい」——バッチファイルでのファイル削除は自動化の定番です。本記事では del コマンドのオプション全解説から、forfiles による日付条件付き削除、rd でのフォルダ削除、誤削除を防ぐ安全パターン、よくある落とし穴まで体系的に解説します。
delコマンドの全オプション(/Q /F /S /A)の意味と使い方- ワイルドカードで特定の拡張子・ファイル名パターンのファイルを一括削除
forfiles /d -30で「30日より古いファイル」を自動削除する方法rd /s /qでフォルダごと中身ごと削除する方法- 削除前の存在確認・削除ログ記録による安全な運用パターン
- 読み取り専用・隠しファイルの削除方法と落とし穴
del コマンドによる削除はゴミ箱を経由しません。削除したファイルは即座に復元できなくなります。本番環境で実行する前には必ず 削除対象の確認 を行い、重要なファイルには事前バックアップを取っておきましょう。
del コマンドの構文と主なオプション
del [オプション] [ファイルパス] erase [オプション] [ファイルパス] ← del の別名 主なオプション: /Q : 確認プロンプトを表示しない(Quiet) /F : 読み取り専用ファイルも強制削除(Force) /S : 指定フォルダ以下のサブフォルダも再帰的に削除 /A:H : 隠し属性(Hidden)のファイルを対象にする /A:R : 読み取り専用(Read-only)属性のファイルを対象にする /A:S : システム属性のファイルを対象にする /P : ファイルごとに削除確認を求める(対話モード)
| 操作 | 構文例 | 説明 |
|---|---|---|
| 単一ファイルを削除 | del /Q "pathfile.txt" |
確認なしで削除 |
| 拡張子一括削除 | del /Q "path*.log" |
.log を全て削除 |
| 読み取り専用も削除 | del /F /Q "path*.bak" |
強制削除 |
| サブフォルダも再帰削除 | del /S /Q "path*.tmp" |
全階層の .tmp を削除 |
| フォルダごと削除 | rd /s /q "folder" |
中身ごとフォルダを削除 |
| 日付条件付き削除 | forfiles /p path /m *.log /d -30 /c "cmd /c del @file" |
30日以上古いファイルを削除 |
方法1: 単一ファイルを削除する
基本: 指定ファイルを削除
@echo off
setlocal
set TARGET=C:worklogsapp.log
rem ファイルが存在する場合のみ削除
if exist "%TARGET%" (
del /Q "%TARGET%"
if errorlevel 1 (
echo [ERROR] 削除に失敗しました: %TARGET%
) else (
echo [OK] 削除しました: %TARGET%
)
) else (
echo [SKIP] ファイルが存在しません: %TARGET%
)
endlocal
方法2: ワイルドカードで複数ファイルを一括削除
特定の拡張子をまとめて削除
@echo off setlocal set LOGDIR=C:worklogs rem .log ファイルを全て削除(確認なし) del /Q "%LOGDIR%*.log" rem .tmp と .bak もまとめて削除 del /Q "%LOGDIR%*.tmp" del /Q "%LOGDIR%*.bak" echo 削除完了 endlocal
ファイル名パターンで絞り込んで削除
@echo off setlocal set LOGDIR=C:worklogs rem "temp_" で始まるファイルを削除 del /Q "%LOGDIR% emp_*.*" rem "debug" を含む .log ファイルを削除 del /Q "%LOGDIR%*debug*.log" endlocal
サブフォルダも含めて再帰的に削除
@echo off setlocal set WORKDIR=C:work rem /S でサブフォルダも含めて全 .tmp を削除 del /S /Q "%WORKDIR%*.tmp" echo サブフォルダを含む .tmp ファイルを削除しました endlocal
del /S /Q "*.tmp" を実行すると、削除したファイルが含まれていたフォルダ名が標準出力に表示されます。これはエラーではなく仕様の動作です。
>nul を付けるとフォルダ名の表示も抑制できます。なお
del /S はファイルを削除しますが、空になったフォルダは削除しません。
方法3: forfiles で日付条件付き削除
forfiles を使うと「N日以上古いファイルを削除」という日付条件を付けられます。ログ自動削除の定番パターンです。
30日より古いファイルを削除
@echo off
setlocal
set LOGDIR=C:worklogs
rem 更新日が30日以上前の .log ファイルを削除
forfiles /p "%LOGDIR%" /m *.log /d -30 /c "cmd /c del @file"
if errorlevel 1 (
echo 対象ファイルなし(30日以内のファイルのみ)
) else (
echo 古いログファイルを削除しました
)
endlocal
特定日付より前のファイルを削除
@echo off setlocal set LOGDIR=C:worklogs rem 2025年1月1日より前の .log ファイルを削除 forfiles /p "%LOGDIR%" /m *.log /d 2025/01/01 /c "cmd /c del @file" endlocal
サブフォルダも含めて古いファイルを削除
@echo off setlocal set LOGDIR=C:worklogs rem /s でサブフォルダも対象にして60日以上古い .log を削除 forfiles /p "%LOGDIR%" /s /m *.log /d -60 /c "cmd /c del @file" endlocal
forfiles /d -30 の基準は ファイルの最終更新日時 です。作成日ではない点に注意してください。ログファイルが毎日追記されている場合、最終更新日は最新なので
/d -30 の対象になりません。日付付きファイル名で毎日ローテーションしているログには有効です。
方法4: for + del で柔軟なフィルタリング削除
for /f で dir の出力を受け取り、条件を細かく制御して削除します。
特定のファイルだけ除外して残りを削除
@echo off
setlocal enabledelayedexpansion
set LOGDIR=C:worklogs
rem "keep_" で始まるファイルを除いて .log を削除
for %%F in ("%LOGDIR%*.log") do (
echo %%~nxF | findstr /b "keep_" >nul
if errorlevel 1 (
del /Q "%%~fF"
echo 削除: %%~nxF
) else (
echo 保持: %%~nxF
)
)
endlocal
最新N件だけ残して古いファイルを削除
@echo off
setlocal enabledelayedexpansion
set LOGDIR=C:worklogs
set KEEP=5
rem ファイル数を数える
set TOTAL=0
for %%F in ("%LOGDIR%*.log") do set /a TOTAL+=1
set /a DELETE_COUNT=%TOTAL%-%KEEP%
if !DELETE_COUNT! LEQ 0 (
echo 削除不要: %TOTAL% ファイル(KEEP=%KEEP% 以内)
goto :end
)
rem 更新日が古い順に並べて超過分を削除
set CNT=0
for /f "delims=" %%F in ('dir /b /a-d /o:d "%LOGDIR%*.log"') do (
if !CNT! LSS !DELETE_COUNT! (
del /Q "%LOGDIR%\%%F"
echo 削除: %%F
set /a CNT+=1
)
)
echo 完了: !CNT! ファイルを削除しました
:end
endlocal
ログの世代管理・自動削除の実装詳細は バッチファイルでログローテーションを実装する方法 で詳しく解説しています。
フォルダごと削除する(rd / rmdir)
フォルダとその中身をまとめて削除するには rd(または rmdir)を使います。
基本: フォルダと中身をまとめて削除
@echo off
setlocal
set TARGET_DIR=C:work mp
rem フォルダが存在する場合のみ削除
if exist "%TARGET_DIR%" (
rem /s: サブフォルダも含む /q: 確認なし
rd /s /q "%TARGET_DIR%"
if errorlevel 1 (
echo [ERROR] フォルダ削除に失敗しました
) else (
echo [OK] フォルダを削除しました: %TARGET_DIR%
)
) else (
echo [SKIP] フォルダが存在しません: %TARGET_DIR%
)
endlocal
フォルダの中身だけ削除してフォルダ自体は残す
@echo off
setlocal
set TARGET_DIR=C:work mp
rem フォルダの中身(ファイルのみ)を削除
del /Q /F "%TARGET_DIR%*.*"
rem 中のサブフォルダも削除したい場合
for /d %%F in ("%TARGET_DIR%*") do (
rd /s /q "%%~fF"
)
echo フォルダの中身を削除しました(フォルダ自体は残っています)
endlocal
rd /s /q "フォルダ" は指定フォルダと中身を全て削除します。ゴミ箱に入らず、確認プロンプトも出ません。特に変数でパスを組み立てる場合、変数が空文字になると意図しない上位フォルダを削除する恐れがあります。
変数が空でないことを
if "%TARGET_DIR%"=="" で確認してから実行することを強く推奨します。
存在確認してから安全に削除する
@echo off
setlocal
set LOGDIR=C:worklogs
rem === 安全確認チェック ===
rem 1. 変数が空でないことを確認
if "%LOGDIR%"=="" (
echo [ERROR] 削除対象パスが空です。処理を中止します
exit /b 1
)
rem 2. 削除対象フォルダが存在することを確認
if not exist "%LOGDIR%" (
echo [ERROR] フォルダが存在しません: %LOGDIR%
exit /b 1
)
rem 3. 削除前に対象ファイルをリスト表示して確認
echo === 削除予定ファイル ===
dir /b "%LOGDIR%*.log" 2>nul
echo =======================
rem 4. 削除実行
del /Q "%LOGDIR%*.log"
echo [OK] 削除完了
endlocal
IF EXIST での存在確認の詳細は IF EXISTでファイル・フォルダの存在確認をする方法 を参照してください。
実践例A: 30日より古いログを自動削除してレポートを残す
@echo off
setlocal enabledelayedexpansion
set LOGDIR=C:worklogs
set REPORT=%~dp0delete_report.log
set DAYS=30
rem レポートヘッダー
(
echo ===========================
echo 削除実行日時: %DATE% %TIME%
echo 対象フォルダ: %LOGDIR%
echo 削除条件: %DAYS%日以上古いファイル
echo ===========================
) >> "%REPORT%"
rem 削除前のファイル数を記録
set BEFORE=0
for %%F in ("%LOGDIR%*.log") do set /a BEFORE+=1
rem 古いファイルを削除(削除ファイル名もレポートに記録)
forfiles /p "%LOGDIR%" /m *.log /d -%DAYS% /c "cmd /c (echo 削除: @file >> "%~dp0delete_report.log"" ^& del @file)"
rem 削除後のファイル数を記録
set AFTER=0
for %%F in ("%LOGDIR%*.log") do set /a AFTER+=1
set /a DELETED=%BEFORE%-%AFTER%
echo 削除件数: !DELETED! >> "%REPORT%"
echo. >> "%REPORT%"
echo 削除完了: %BEFORE% → !AFTER! ファイル(!DELETED! 件削除)
endlocal
実践例B: 拡張子別に一括削除(複数拡張子対応)
@echo off
setlocal enabledelayedexpansion
set CLEANDIR=C:work mp
rem 削除する拡張子のリスト
for %%E in (tmp bak log~ ~tmp cache) do (
set COUNT=0
for %%F in ("%CLEANDIR%*.%%E") do set /a COUNT+=1
if !COUNT! GTR 0 (
del /Q "%CLEANDIR%*.%%E"
echo .%%E を !COUNT! ファイル削除しました
) else (
echo .%%E ファイルなし(スキップ)
)
)
endlocal
実践例C: サイズ0のファイルを一括削除
@echo off
setlocal
set TARGETDIR=C:worklogs
rem ファイルサイズが 0 バイトのファイルを全て削除
for %%F in ("%TARGETDIR%*.*") do (
if %%~zF == 0 (
del /Q "%%~fF"
echo 空ファイル削除: %%~nxF
)
)
endlocal
ファイルサイズを条件に使う詳細は バッチファイルでファイルサイズを取得して条件分岐する方法 を参照してください。
実践例D: 削除ログをCSVに記録して安全に運用する
@echo off
setlocal enabledelayedexpansion
set LOGDIR=C:worklogs
set CSVLOG=%~dp0delete_history.csv
rem ヘッダー(初回のみ)
if not exist "%CSVLOG%" (
echo 日時,ファイル名,サイズ(bytes),削除結果 > "%CSVLOG%"
)
for %%F in ("%LOGDIR%*.log") do (
set FNAME=%%~nxF
set FSIZE=%%~zF
del /Q "%%~fF"
if not errorlevel 1 (
set RESULT=OK
) else (
set RESULT=FAIL
)
echo %DATE% %TIME%,!FNAME!,!FSIZE!,!RESULT! >> "%CSVLOG%"
echo !RESULT!: !FNAME!
)
endlocal
読み取り専用・隠しファイルを削除する
@echo off setlocal set TARGETDIR=C:work mp rem /F : 読み取り専用属性のファイルも強制削除 del /F /Q "%TARGETDIR%*.bak" rem /A:H : 隠し属性のファイルを削除 del /A:H /Q "%TARGETDIR%*.*" rem /F /A:H /A:S : 読み取り専用・隠し・システム属性をすべて削除 del /F /A:H /A:S /Q "%TARGETDIR%*.*" endlocal
/A:H(隠し)、/A:R(読み取り専用)、/A:S(システム)は組み合わせて指定できます。/A:-H のように - を付けると「その属性を持たないファイル」を対象にできます。例:
del /A:-H /Q = 隠し属性を持たない通常ファイルのみ削除
よくある落とし穴
落とし穴1: 対象ファイルがゼロ件でもエラーと見なされる
rem del は削除対象が1件もないと "ファイルが見つかりません" を表示し
rem ERRORLEVEL=1 を返す
rem → "真のエラー" と区別するには削除前に存在確認する
if exist "%LOGDIR%*.log" (
del /Q "%LOGDIR%*.log"
echo 削除完了
) else (
echo 削除対象ファイルなし
)
落とし穴2: パスにスペースがある場合はダブルクォート必須
rem NG: スペースを含むパスをクォートなしで指定するとエラー del C:My Folder*.log rem → "C:My" と "Folder*.log" に分断される rem OK: ダブルクォートで囲む del /Q "C:My Folder*.log"
落とし穴3: ループ内で %ERRORLEVEL% は正しく更新されない
rem NG: for ブロック内で %ERRORLEVEL% を参照すると古い値のまま
@echo off
setlocal
for %%F in (*.log) do (
del "%%F"
if %ERRORLEVEL% == 0 echo OK ← 常に0になる可能性がある
)
rem OK: if errorlevel を使う(%ERRORLEVEL% 変数を参照しない)
@echo off
setlocal
for %%F in (*.log) do (
del "%%F"
if not errorlevel 1 echo OK: %%F
if errorlevel 1 echo FAIL: %%F
)
落とし穴4: rd /s /q で変数が空だとカレントまたは上位フォルダを削除する
rem 危険な例: TARGET_DIR が空だった場合
set TARGET_DIR=
rd /s /q "%TARGET_DIR%" ← "rd /s /q """ と解釈される場合がある
rem 必ず変数の空チェックを行ってから実行
if "%TARGET_DIR%"=="" (
echo [ERROR] 削除対象パスが空です。処理を中止します
exit /b 1
)
rd /s /q "%TARGET_DIR%"
落とし穴5: del はフォルダを削除できない(del でフォルダ指定するとエラー)
rem NG: del でフォルダを指定してもフォルダは削除されない del /Q "C:work mp" ← フォルダなので何もしない(またはエラー) rem OK: フォルダの削除は rd を使う rd /s /q "C:work mp" rem フォルダの中身(ファイル)だけ削除してフォルダ自体を残したい場合 del /Q "C:work mp*.*"
よくある質問(FAQ)
del コマンドで削除したファイルはゴミ箱を経由しないため、通常は復元できません。ファイルが上書きされる前であればディスク復元ツール(Recuva 等)で回復できる場合がありますが、確実性はありません。重要なファイルは削除前にバックアップを取ることを強く推奨します。
rem 削除前にバックアップを取るパターン set SRC=C:worklogs set BAK=C:worklogs_backup if not exist "%BAK%" mkdir "%BAK%" xcopy "%SRC%*.log" "%BAK%" /Y >nul del /Q "%SRC%*.log" echo バックアップ後に削除しました
for ループ内でカウンタを使って進捗を表示できます。
@echo off
setlocal enabledelayedexpansion
set LOGDIR=C:worklogs
rem 総数を先に数える
set TOTAL=0
for %%F in ("%LOGDIR%*.log") do set /a TOTAL+=1
rem 削除しながら進捗表示
set CNT=0
for %%F in ("%LOGDIR%*.log") do (
del /Q "%%~fF"
set /a CNT+=1
echo [!CNT!/%TOTAL%] 削除: %%~nxF
)
echo 完了: !CNT! ファイルを削除しました
endlocal
for と findstr を組み合わせてファイル名を絞り込みます。
@echo off
setlocal
set LOGDIR=C:worklogs
rem ファイル名に "error" を含む .log ファイルだけ削除
for %%F in ("%LOGDIR%*.log") do (
echo %%~nxF | findstr /i "error" >nul
if not errorlevel 1 (
del /Q "%%~fF"
echo 削除: %%~nxF
)
)
endlocal
ファイル名に含まない文字列での削除は ファイル名に指定文字列を含まないファイルを削除する方法 も参照してください。
削除スクリプトをタスクスケジューラに登録します。
rem 毎日深夜2時に実行するタスクを登録(管理者権限で実行) schtasks /create /tn "AutoDeleteOldLogs" ^ /tr "cmd /c "C:atchdelete_old_logs.bat"" ^ /sc daily /st 02:00 /ru "%USERNAME%" /f rem 登録確認 schtasks /query /tn "AutoDeleteOldLogs" /fo list rem タスクを削除する場合 schtasks /delete /tn "AutoDeleteOldLogs" /f
set /p で入力を受け取り、Y/N で分岐します。
@echo off
setlocal
set LOGDIR=C:worklogs
rem 削除予定ファイルを表示
echo 以下のファイルを削除します:
dir /b "%LOGDIR%*.log" 2>nul
echo.
rem 確認入力
set /p CONFIRM=続行しますか? (Y/N):
if /i "%CONFIRM%"=="Y" (
del /Q "%LOGDIR%*.log"
echo 削除しました
) else (
echo キャンセルしました
)
endlocal
まとめ
| 目的 | 推奨方法 |
|---|---|
| 単一ファイルを削除 | del /Q "pathfile.txt" |
| 拡張子一括削除 | del /Q "path*.log" |
| 読み取り専用も強制削除 | del /F /Q "path*.bak" |
| サブフォルダも再帰削除 | del /S /Q "path*.tmp" |
| フォルダごと削除 | rd /s /q "folder" |
| 日付条件付き削除 | forfiles /p path /m *.log /d -30 /c "cmd /c del @file" |
| 最新N件だけ残す | dir /o:d + for /f + del |
| 特定文字列を含むファイル削除 | for + findstr + del |
| 安全な削除(空チェック付き) | 削除前に変数チェック・if exist 確認 |
ファイルの移動については ファイルを別フォルダに移動する方法完全ガイド を、ログの世代管理・自動削除の実装詳細は バッチファイルでログローテーションを実装する方法 を参照してください。