Windowsのforfilesコマンドで条件に合うファイルを取り出して処理するTech TIPS

特定のフォルダ下にある*.docファイルや、3カ月以上前のファイルだけを削除したいといった場合、まず条件に合うファイルだけを抽出する必要がある。forfilesコマンドを使うと、このようなファイルだけを取り出してコマンド処理できる。

» 2009年02月27日 00時00分 公開
[打越浩幸デジタルアドバンテージ]
「Tech TIPS」のインデックス

連載目次

対象OS:Windows Server 2003/Windows Vista/Windows Server 2008



解説

 あるフォルダーの下にあるファイルを全て走査して、例えば6カ月以上更新されていないものを抽出/削除したり、特定のテキスト処理(パイプによるコマンドの連続適用など)を行ったりしたい場合、どのようにすればよいだろうか。

 コマンドプロンプト上でfor /rコマンドを使えば再帰的なファイルの走査は可能だ。しかし、forコマンドでは特定の更新日付を持つファイルだけを抽出することはできない。

 PowerShellを使えば、特定の条件を満たすファイルだけを抽出できる(具体的な手順は右側の関連記事を参照)。しかし、これはPowerShellがインストールされている環境でしか使えないし、何よりPowerShellを新たに覚える必要もある。

 従来のコマンドプロンプトでの操作に馴れたユーザーなら、このような場合はforfiles.exeコマンドを利用するとよいだろう。これは指定されたフォルダーの下を(必要なら再帰的に)走査して条件に合うファイルやフォルダーを抽出し、それを基にして指定されたコマンドを実行するという機能を持つ。

 見つかったファイルやフォルダーのパス名やサイズ、日付などは変数として取り出すことができるので、実行するコマンドの引数にその変数を指定すれば、さまざまな処理が可能になる。ファイルのバックアップや不要な過去のファイルの削除、テキスト処理などに活用できるだろう。本TIPSではこのforfilesコマンドについて紹介する。

 なお、このコマンドはWindows Server 2003以降(Windows VistaやWindows Server 2008も含む)でしか利用できない(ライセンス的にはともかく、動かすだけならWindows XP上でも利用できるようである)。Windows 2000のリソースキットには、Windows 2000向けの古いバージョンのものが収録されている。

操作方法

●forfilesの使い方

 forfilesコマンドの使い方は「forfiles /?」とすると表示される。

C:\>forfiles /?

FORFILES [/P パス名] [/M 検索マスク] [/S]
         [/C コマンド] [/D [+ | -] {yyyy/MM/dd | dd}]

説明:
    ファイル (または、ファイルのセット) を選んで、そのファイル上の
    コマンドを実行します。これはバッチ ジョブの使用に便利です。

パラメータ一覧:
    /P    パス名        検索を開始するパスを示します。
                        既定のフォルダーは現在実行中の
                        ディレクトリ (.) です。
……(以下省略)……



●フォルダーのスキャンとファイル/フォルダーの列挙

 forfilesを何も引数無しで実行すると、現在のフォルダーにあるファイルやフォルダーの一覧が表示され、/sオプションを付けると、サブフォルダーも含めた一覧が表示される。

C:\Document>forfiles ……カレントフォルダーの一覧

"Doc1 (1).doc" ……結果のファイル一覧が1行に1つずつ表示される
"Doc1 (2).doc"
"Doc1 (3).doc"
"Doc1 (4).doc"
"Folder1" ……フォルダーも一覧表示される
"Folder2"

C:\Document>forfiles /s ……サブフォルダー以下も全て含めた一覧

"Doc1 (1).doc"
"Doc1 (2).doc"
"Doc1 (3).doc"
"Doc1 (4).doc"
"Folder1"
"Folder2"
"Folder1document (11).doc" ……以下、サブフォルダーの内容
"Folder1document (12).doc"
"Folder1document (13).doc"
"Folder1document (14).doc"
"Folder1document (15).doc"
"Folder3"
"doc3 (1).doc"
"doc3 (2).doc"
……(以下省略)……



 デフォルトではカレントフォルダー内をスキャンするが、「forfiles /p D:\Prj」のように/pオプションを付けると、指定されたフォルダーからスキャンを開始する。

 「/m *.doc」というように/mオプションを使うと、特定の名前パターンにマッチするファイルやフォルダー名のみが列挙される。

●コマンドの実行

 上の例では単にファイル名が表示されているだけであるが、これは実は「cmd /c echo @file」というデフォルトコマンドを実行した結果である。別のコマンドを実行したければ、/cオプションを使ってコマンドを指定する。

 ただしコマンドプロンプト(cmd.exe)の内部コマンドの場合は「forfiles /c "cmd /c dir 〜"」のように、「cmd /c」に続けて、内部コマンドを指定する。外部プログラムの場合はそのまま指定してもよい。この辺りは、forコマンドなどと同じである。

 これを使えば、例えば「forfiles /c "cmd /c del @file"」としてファイルを削除できるし、「forfiles /c "mytextfilter @file"」として外部プログラムmytextfilter.exeを実行することもできる(1つのファイルやフォルダー名ごとに、プログラムが1回起動する)。ここで「@file」はスキャンされたファイル名を表す変数である。forfilesの/cオプション中では以下のような変数が利用できるので、実行したいコマンドの引数として渡せばよい。

変数 意味
@file ファイル名(拡張子も含む)
@fname 拡張子無しの基本ファイル名部分
@ext 拡張子
@path ファイルのフルパス名
@relpath 開始フォルダーからのファイルの相対パス名
@isdir フォルダー名ならTRUE、ファイル名ならFALSE。if内部コマンドと組み合わせ、「/C "cmd /c if @isdir==FALSE notepad.exe @file"」などのように利用する
@fsize ファイルサイズ(bytes単位)
@fdate ファイルの更新日
@ftime ファイルの更新時間
forfilesのコマンド中で利用可能な変数
コマンド中で特殊文字を使いたければ0x09のように指定する。詳細はforfilesコマンドのヘルプを参照のこと。

 全変数を指定してみると、例えば次のようになる(名前中に「2」を含むものだけを列挙している)。

C:\Document>forfiles /m *2* /c "cmd /c echo @file、@fname、@ext、@path、@relpath、@isdir、@fsize、@fdate、@ftime"

"Doc1 (2).doc"、"Doc1 (2)"、"doc"、"C:\Document\Doc1 (2).doc"、"\Doc1 (2).doc"、FALSE、74240、2009/02/21、11:27:36
"Folder2"、"Folder2"、""、"C:\Document\Folder2"、"\Folder2"、TRUE、0、2009/02/21、14:44:49



●更新時間で対象ファイルを絞り込む

 /dオプションを使うと、ファイルの更新日付に基づいてファイルを抽出できる。例えば「/d -2008/12/31」とすれば2008年年末までの日付を持つファイルがマッチし、「/d -30」とすれば30日以上前のファイルのみがマッチする。

指定 意味
/d +YYYY/MM/DD 「YYYY/MM/DD」は年月日。指定された日付以降のもののみがマッチ。例:「/d +2009/01/01」なら2009年以降にマッチ
/d -YYYY/MM/DD 指定された日付以前のもののみがマッチ。例:「/d -2008/12/31」なら2008年かそれ以前にマッチ
/d +NNN NNNは日数を表す数字。本日より、NNN日以降のもののみがマッチ(未来の日付を持つファイルの抽出)
/d -NNN 本日よりNNN日以前のもののみがマッチ
/dオプションで利用可能な日付/日数指定
「-」を付けるとその日以前のものがマッチし、「+」を付けるとその日以降のものがマッチする。省略すると「+」とみなされる。

 この指定方法を使えば、例えば3カ月以上前の(更新日付を持つ)ファイルだけを削除するということが簡単にできる。

C:\Document\Folder1>forfiles /d -90 ……3カ月(90日)以上前のファイルの抽出

"Folder1document (11).doc" ……結果
"Folder1document (12).doc"

C:\Document\Folder1>forfiles /d -90 /c "cmd /c echo del @file" ……確認してみる

del "Folder1document (11).doc" ……このようなコマンドが実行される
del "Folder1document (12).doc"

C:\Document\Folder1>forfiles /d -90 /c "cmd /c del @file" ……実行



「Tech TIPS」のインデックス

Tech TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。