FORFILES(ファイルの一括処理)

にメンテナンス済み

「30 日以上前のログファイルだけを削除したい」「特定の拡張子のファイルすべてに同じ処理を行いたい」といった場面があります。

FORFILES コマンドは、条件に合うファイルを選び出し、1 つずつに対して、指定したコマンドを実行するコマンドです。ファイルの更新日時で絞り込めるため、古いファイルの整理に向いています。

基本的な使い方

FORFILES [/P ディレクトリ] [/M 検索マスク] [/S] [/C "コマンド"] [/D [+|-]日付または日数]

すべてのオプションは省略できます。省略した場合は、カレントディレクトリにあるすべてのファイルとフォルダーの名前を表示します。

forfiles
- □ ×
コマンド プロンプトのアイコン
コマンド プロンプト
Microsoft Windows [Version xx.x.xxxxx.xxx]
(c) 2026 Ribbit App Development All rights reserved.
 
C:\users\user>forfiles
“backup.cmd"
"report.txt"
"logs”
C:\users\user>

名前がダブルクォーテーションで囲まれて表示される点に注意してください。

主要オプション

オプション説明
/P ディレクトリ検索を開始するディレクトリ(省略時はカレントディレクトリ)
/M 検索マスク対象とするファイル名。ワイルドカードが使える(省略時はすべてのファイル)
/Sサブディレクトリも再帰的に検索する
/C "コマンド"各ファイルに対して実行するコマンド(省略時は cmd /c echo @file)
/D 日付または日数最終更新日で絞り込む。次の節で詳しく解説

拡張子を指定してファイルを処理する

/M で対象を絞り、/C で実行するコマンドを指定します。

forfiles /M *.log /C "cmd /c echo @file"

/C のコマンドの中では、処理中のファイルの情報を @変数 で参照できます。

変数内容
@fileファイル名(拡張子を含む)
@fname拡張子を除いたファイル名
@ext拡張子(ドットは含まない)
@pathファイルのフルパス
@relpath/P で指定したディレクトリからの相対パス
@isdirディレクトリなら TRUE、ファイルなら FALSE
@fsizeファイルサイズ(バイト)
@fdate最終更新日
@ftime最終更新時刻
forfiles /P C:\Logs /M *.log /C "cmd /c echo @path @fsize バイト"
- □ ×
コマンド プロンプトのアイコン
コマンド プロンプト
Microsoft Windows [Version xx.x.xxxxx.xxx]
(c) 2026 Ribbit App Development All rights reserved.
 
C:\users\user>forfiles /P C:\Logs /M *.log /C "cmd /c echo @path @fsize バイト"
”C:\Logs\app.log” 20480 バイト
”C:\Logs\error.log” 1024 バイト
C:\users\user>
おすすめ書籍※ 広告を含む場合があります
中小企業経営者のためのRPA入門 RPA導入を成功させる方法

中小企業経営者のためのRPA入門 RPA導入を成功させる方法

60分でわかる! AIエージェント 超入門

60分でわかる! AIエージェント 超入門

コマンドラインの黒い画面が怖いんです。

コマンドラインの黒い画面が怖いんです。

知識・才能ゼロでもらく~に月10万円稼ぐ! よくわかるAI副業超入門

知識・才能ゼロでもらく~に月10万円稼ぐ! よくわかるAI副業超入門

@path と @file にはダブルクォーテーションが付く

@file や @path は、値の前後にダブルクォーテーションが付いた状態で展開されます。そのため、del @path のようにそのまま渡せば、スペースを含むパスでも正しく動作します。"@path" のように自分で囲む必要はありません。

内部コマンドは cmd /c 経由で実行する

FORFILES は、/C で指定されたコマンドを別プロセスとして起動します。echo や del のようにコマンドプロンプトに組み込まれた内部コマンドは単独の実行ファイルではないため、cmd /c を付けて呼び出す必要があります。

forfiles /M *.txt /C "echo @file"
forfiles /M *.txt /C "cmd /c echo @file"

/C を省略したときの既定値が cmd /c echo @file であるのも、同じ理由です。

チェック

.exe ファイルのような外部コマンドであれば、cmd /c なしでも実行できます。たとえば forfiles /M *.txt /C "notepad @file" です。

更新日時で絞り込む(/D)

/D オプションは、ファイルの最終更新日で対象を絞り込みます。日数または日付で指定できます。

指定方法意味
/D -30最終更新日が 30 日前以前のファイル
/D -2025/01/01最終更新日が 2025 年 1 月 1 日以前のファイル
/D 2025/01/01最終更新日が 2025 年 1 月 1 日以降のファイル

符号を省略した場合は + として扱われます。日付の形式は OS の地域設定に依存します(日本語環境では yyyy/MM/dd、Microsoft の資料では MM/DD/YYYY)。@fdate の出力形式も同様に地域設定に従います。日数での指定であれば、形式の違いを気にする必要はありません。

forfiles /P C:\Logs /M *.log /D -7 /C "cmd /c echo @file @fdate"
日数の指定は「以前」を含む

/D -30 は「30 日前の日付と同じか、それより古い」ファイルを対象にします。ちょうど 30 日前に更新されたファイルも含まれる点に注意してください。

古いファイルを安全に削除する

ログの定期削除は、FORFILES の代表的な使い道です。ただし、削除は元に戻せないため、必ず次の 2 段階で進めてください。

手順 1:削除せず、対象を表示して確認する

forfiles /P C:\Logs /M *.log /S /D -30 /C "cmd /c if @isdir==FALSE echo @path"

手順 2:表示された対象に問題がなければ、echo を del に置き換える

/M *.log はフォルダーにも一致するため、if @isdir==FALSE でファイルだけに限定しています。プレビューと削除で同じ条件を使ってください。

forfiles /P C:\Logs /M *.log /S /D -30 /C "cmd /c if @isdir==FALSE del @path"
del は元に戻せない

del で削除したファイルはごみ箱に入りません。/P のパスを誤ると、意図しないファイルを削除してしまいます。実行前に、手順 1 で必ず対象を確認してください。

サブフォルダーを含めて処理する(/S)

/S を付けると、/P で指定したディレクトリ以下のすべてのサブフォルダーも対象になります。

forfiles /P C:\Docs /S /M *.txt /C "cmd /c echo @relpath"

@relpath は ".\sub\note.txt" のように、/P で指定したディレクトリからの相対パスを返します。

フォルダーだけを対象にする

@isdir を使うと、ファイルとフォルダーを区別できます。

forfiles /P C:\Docs /C "cmd /c if @isdir==TRUE echo @file"

特殊文字を指定する

/C の中でダブルクォーテーションなどを使いたい場合は、0xHH の形式で 16 進数のコードを指定できます。

forfiles /M *.txt /C "cmd /c echo 0x22@fname0x22"
- □ ×
コマンド プロンプトのアイコン
コマンド プロンプト
Microsoft Windows [Version xx.x.xxxxx.xxx]
(c) 2026 Ribbit App Development All rights reserved.
 
C:\users\user>forfiles /M *.txt /C "cmd /c echo 0x22@fname0x22"
“readme"
"memo”
C:\users\user>

0x22 はダブルクォーテーション(")を表します。

バッチファイルで使うときのポイント

対象が見つからない場合

条件に合うファイルが 1 つもなかった場合、FORFILES はエラーメッセージを表示し、ERRORLEVEL に 0 以外の値を設定します。バッチファイルで「対象なし」を判定したいときに利用できます。ただし、パスの誤りなど他のエラーでも 1 になるため、厳密な判定には向きません。

@echo off
forfiles /P C:\Logs /M *.log /D -30 >nul 2>&1
if errorlevel 1 (
    echo 削除対象のログはありません。
) else (
    echo 30 日以上前のログが見つかりました。
)

バッチファイル内の % について

FORFILES の @変数は @ で始まるため、バッチファイル内でも % を重ねる必要はありません。一方、%LOG_DIR% のような変数をパスに使う場合は、スペース対策としてダブルクォーテーションで囲んでください。

@echo off
set LOG_DIR=C:\My Logs
set DAYS=30

forfiles /P "%LOG_DIR%" /M *.log /S /D -%DAYS% /C "cmd /c echo @path"
FOR コマンドとの使い分け

ファイル名の一覧に対して処理を繰り返すだけなら FOR コマンドでも実現できます。ただし FOR では更新日時を簡単には比較できないため、日付条件が必要なときは FORFILES が便利です。

まとめ

操作コマンド
ファイル名を一覧表示forfiles /M *.log
内部コマンドを実行するforfiles /C "cmd /c echo @file"
サブフォルダーも対象にするforfiles /S
N 日以上前のファイルを抽出forfiles /D -N
開始ディレクトリを指定forfiles /P ディレクトリ
フルパスで処理する@path

関連記事

練習問題

練習問題

最終更新日が 30 日以上前のファイルを一覧表示するコマンドはどれでしょうか?

回答がサーバーに送信されることはありません
練習問題

FORFILES の /C で echo や del を実行するとき、cmd /c を付けるのはなぜでしょうか?

回答がサーバーに送信されることはありません
練習問題

FORFILES で古いファイルを削除するとき、安全のために最初に行うべきことはどれでしょうか?

回答がサーバーに送信されることはありません
#コマンドプロンプト #バッチファイル #FORFILES #コマンド #ファイル操作