Programming Field

Forfiles - DOS/コマンドプロンプト コマンド一覧

[Windows Vista以降] ディレクトリにあるファイル/サブディレクトリそれぞれに対してコマンドを実行します。

構文

forfiles[.exe] [/P <path>] [/S] [/M <mask>]
  [/C <command>] [/D [+ | -][yyyy/MM/dd | dd]]

オプション一覧

/P <path> コマンドを実行するファイルやサブディレクトリがある親ディレクトリを指定します。既定値は「.」(カレントディレクトリ)です。
/S ファイルやサブディレクトリの探索(列挙)範囲をサブディレクトリ以下にも広げます。既定では対象のディレクトリ直下のみとなります。
/M <mask> ファイルやサブディレクトリの絞り込み(フィルター)を行うための名前に対する条件を指定します。<mask> には拡張子部分も含めてワイルドカードで条件を指定します。既定では「*」が使用され、すべてのファイル/サブディレクトリが列挙されます。
/C <command>

実行するコマンドラインを指定します。コマンドラインの中にスペースを含む場合は全体をダブルクオーテーション「" "」で括る必要があります。省略した場合は「"cmd /c echo @file"」が指定されたものとみなし、ファイル名を出力します。

コマンドラインではファイル名などを得るための特別な記述を利用することができます。詳しくは解説をご覧ください。

/D [+ | -][yyyy/MM/dd | dd]

ファイルやサブディレクトリの絞り込み(フィルター)を行うための最終更新日(日付)を指定します。「+」または「-」を指定し、スペースを挟まずに日付または「N日後(前)」の「N」にあたる日数を続けて指定します。なお、「+」または「-」は省略可能で省略した場合は「+」として扱われます。

「+」または「-」は日付の前後どちらで絞り込むかを決定します。「+」は「特定の日付またはそれ以降」、「-」は「特定の日付またはそれ以前」で絞り込みます。なお「時刻」は無視され、「日付」部分のみでの比較が行われます。

yyyy/MM/dd」または「dd」は実際の絞り込み範囲を決定します。「yyyy/MM/dd」の指定では起点となる日付を「年4桁」「/」「月2桁」「/」「日2桁」の形式で指定します。一方「dd」のみの指定は現在の日付を基準とした日数を表します。「+5」であれば5日後、「-3」であれば3日前を範囲の起点とし、それぞれその日付以降/以前を絞り込み範囲とします。

解説

ForfilesはForコマンドと同様にファイルやサブディレクトリを列挙して特定のコマンドを実行したい場合に利用します。Forはcmd.exeの内部コマンドであるのに対しForfilesは独立したプログラムであるため、バッチファイル等での利用方法が異なる場合があります。注意点として、内部コマンド(EchoコマンドCopyコマンドなど)を使う場合は明示的にCmdプログラムを使って「forfiles /C "cmd /S /C \"コマンド @file\""」などと指定する必要があります

Forfilesに指定するコマンドラインでは、以下の特別な記述を利用することができます。これらを利用して列挙したファイルやサブディレクトリに関する情報を得ることができます。

記述 意味 展開例
@file ファイル名に置き換わります。 "note.201311.txt"
@fname ファイル名のうち拡張子を除いたものに置き換わります。 "note.201311"
@ext 拡張子に置き換わります。ドットは含まれません。 "txt"
@path ファイルの完全パス名に置き換わります。 "D:\MyDocs\Text Documents\note.201311.txt"
@relpath ファイルの相対パス名に置き換わります。/P で指定したパスが基準になります。 ".\Text Documents\note.201311.txt"
@isdir 対象がディレクトリであれば「TRUE」、ファイルであれば「FALSE」に置き換わります。 FALSE
@fsize ファイルサイズに置き換わります(バイト単位、区切り文字や単位を表す文字はありません)。ディレクトリの場合は 0 になります。 34122
@fdate ファイルの更新日に置き換わります。形式はシステム設定の「短い形式」に従います。 2013/11/30
@ftime ファイルの更新時刻に置き換わります。形式はシステム設定の「短い形式」に従います。 17:25:23

また、コマンドラインでは以下の文字を利用できます。

  • 0xHH (16進数2桁) - 数値を文字コード(拡張を含むASCII文字コード)として、そのコードに対応する文字が使用されます。(現在の環境におけるコードページの影響は受けず、常にASCII文字コードとして扱われます。)
  • \" - ダブルクオーテーション「"」をコマンドラインの一部として用いる場合は、その前に「\」を付けて「\"」とします。特にコマンドラインの先頭に指定するプログラムのパスにスペースを含む場合は、\"X:\Path To\Program.exe\" parameters... のようにする必要があります(ただし解釈にバグ(?)があるようで、これを行った場合プログラムに渡されるコマンドラインの先頭が「"」になるようです)。

※ Forfilesがコマンドを実行する際、Forfilesは実行するプログラムに渡すコマンドライン(Win32APIのGetCommandLine関数で得られるもの)にプログラム名を含めません(C/C++ における argv の要素が1つずつ先頭側にずれたような形です)。そのため、プログラムによってはプログラム名の直後にダミーの引数を入れないと正常に動作しない可能性があります。

サンプル1

forfiles /M *.*

拡張子の存在するファイル/ディレクトリを列挙し画面に出力します(「.」で始まるファイルも含みます)。この指定は「『.』(ドット)が含まれるファイル名のみに絞る」という意味になるため、「.」を含まないことになる拡張子のないファイル/ディレクトリは対象外になります。

サンプル2

forfiles /P %CD%\data\2017 /S /M *.xml /C "\"D:\My Tools\Parser.exe\" Parser.exe\" /I @path /O \"%CD%\output\2017\""

現在のディレクトリ以下の「data\2017」ディレクトリおよびそのサブディレクトリにある、拡張子が「xml」であるファイルを列挙し、それぞれの絶対パス名を引数の一部として「D:\My Tools\Parser.exe」を実行します。ここではコマンドラインにダミーの引数を加えることで、Parser.exeのコマンドラインの先頭を「"Parser.exe"」としています。例として「Y:\My Documents\data\2017\01.xml」が列挙されると、Parser.exeに渡されるコマンドラインは「"Parser.exe" /I "Y:\My Documents\data\2017\01.xml" /O "Y:\My Documents\output\2017"」となります。

※ このような指定になっているのは前述のForfilesプログラムの引数解釈によるものなので、実際に「"」でプログラム名を括る場合は、そのプログラムにどんなコマンドラインが渡されることになるかを事前に確認することをお勧めします。

関連項目