くんすとの備忘録

IT系技術メモ

移転しました。

15秒後に自動的にリダイレクトします。

コマンドプロンプトで読んでおくべき7つのHELP - その④「for /?」

これは、コマンドプロンプト(cmd.exe) Advent Calendar 2015 - Qiitaの4日目の記事です。

Windows 10 Home 64bit 搭載のcmd.exeにて検証を行っています。

for /?

指定されたコマンドをファイル セットの各ファイルに対して実行します。

FOR %変数 IN (セット) DO コマンド [コマンドパラメーター]

  %変数     単一文字の置き換え可能なパラメーターを指定します。
  (セット)  ファイル セットを指定します。ワイルドカードを使用できます。
  コマンド  各ファイルごとに実行するコマンドを指定します。
  コマンドパラメーター
            指定されたコマンドのパラメーターまたはスイッチを指定します。

バッチ プログラムで FOR コマンドを使用するときは、%変数の代わりに、
%%変数を使用してください。変数名では大文字と小文字が区別されるため、
%i と %I は異なります。

コマンド拡張機能を有効にすると、次の FOR コマンドの追加形式
がサポートされるようになります:

FOR /D %変数 IN (セット) DO コマンド [コマンド パラメーター]

    セットがワイルドカードを含む場合は、ファイル名ではなくディレクトリ名
    の一致を指定します。

FOR /R [[ドライブ:]パス] %変数 IN (セット) DO コマンド [コマンド パラメーター]

    [ドライブ:]パスから始めて、ツリーの各ディレクトリで FOR 文を実行し
    ます。/R の後にディレクトリが指定されていない場合は、現在の
    ディレクトリが使用されます。セットが単一のピリオド (.) である場合は、
    ディレクトリ ツリーの列挙だけを行います。

FOR /L %変数 IN (開始,ステップ,終了) DO コマンド [コマンド パラメーター]

    セットは、ステップの量ごとに変化する開始から終了までの数列です。
    たとえば、(1,1,5) は 1 2 3 4 5、(5,-1,1) は (5 4 3 2 1) という数列に
    なります。

FOR /F ["オプション"] %変数 IN (ファイル セット) DO コマンド
       [コマンド パラメーター]
FOR /F ["オプション"] %変数 IN ("文字列") DO コマンド [コマンド パラメーター]
FOR /F ["オプション"] %変数 IN ('コマンド') DO コマンド [コマンド パラメーター]

    または usebackq オプションの場合:

FOR /F ["オプション"] %変数 IN (ファイル セット) DO コマンド
       [コマンド パラメーター]
FOR /F ["オプション"] %変数 IN ('文字列') DO コマンド [コマンド パラメーター]
FOR /F ["オプション"] %変数 IN (`コマンド`) DO コマンド [コマンド パラメーター]

    ファイル セットは、1 つ以上のファイル名です。各ファイルが開かれ、
    読み取られ、処理されてから、ファイル セットの次のファイルに進みます。
    処理では、ファイルの読み取り、個々のテキスト行への分割と、0 個以上の
    トークンへの解析が行われます。その後、見つかったトークン文字列を変数値に
    設定して for ループの本体が呼び出されます。既定では、/F は、各ファイルの
    各行から、空白で区切られた最初のトークンを取得して渡します。空白行は
    スキップされます。既定の解析動作を変更するには、省略可能な "オプション"
    パラメーターを指定します。これは、異なる解析オプションを指定する 1 つ以上の
    キーワードを含む、引用符で囲まれた文字列です。キーワードは、次のとおりです:

        eol=c           - 行末のコメント文字を指定します (1 文字)。
        skip=n          - ファイルの先頭でスキップする行数を指定します。
        delims=xxx      - 区切り文字のセットを指定します。
                          これは、既定の区切り文字であるスペースとタブを
                          置き換えます。
        tokens=x,y,m-n  - 各繰り返しに対して、各行から for 本体に渡す
                          トークンを指定します。これにより、追加の変数名が
                          割り当てられます。
                          m-n の形式は範囲で、m 番目から n 番目の
                          トークンを指定します。
                          tokens= 文字列の最後の文字がアスタリスクである場合は、
                          追加の変数が割り当てられ、最後のトークンが解析された
                          後、行に含まれている残りのテキストを受け取ります。
        usebackq        - 次の新しい表示形式を指定します。
                          逆引用符で囲まれた文字列がコマンドとして実行され、
                          一重引用符で囲まれた文字列がリテラル文字列コマンドに
                          なり、ファイル セットのファイル名を二重引用符で
                          囲めるようになります。

    例を参考にしてください:

FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k

    この例は、myfile.txt の各行を解析します。セミコロンで始まる行を無視し、
    各行の 2 番目と 3 番目のトークンを for 本体に渡します。
    トークンは、コンマまたはスペースで区切られています。
    for 本体の文が %i で 2 番目のトークンを、%j で 3 番目のトークンを取得し、
    %k で 3 番目以降のすべてのトークンを取得していることに
    注意してください。
    スペースを含むファイル名に対しては、二重引用符でファイル名を引用する
    必要があります。
    この方法で二重引用符を使うためには、usebackq オプションも
    使わなければなりません。
    使わなければ、二重引用符はリテラル文字列の定義として
    解釈され、解析されます。

    %i は for 文で明示的に宣言され、%j と %k は tokens= オプションで暗黙的に
    宣言されています。
    tokens= 行を使って 26 個までのトークンを指定できますが、
    文字 'z' または 'Z' よりも高い変数を宣言することはできません。FOR 変数名は
    単一の文字で、大文字と小文字を区別し、グローバルなものであり、一度に
    アクティブにできるのは合計 52 個までです。

    また、かっこで囲んだファイル セットを一重引用符で囲み、文字列にすることに
    より、即時の文字列に対する FOR /F 解析ロジックを使うこともできます。
    これは、ファイルからの単一入力行として処理されます。

    最後に、FOR /F コマンドを使って、コマンド出力を解析することができます。
    かっこの中のファイル セットを逆引用符で囲みます。この文字列は、コマンド
    ラインとして子 CMD.EXE に渡されます。出力はメモリにキャプチャされ、
    ファイルのように解析されます。
    例:

      FOR /F "usebackq delims==" %i IN (`set`) DO @echo %i

    この例は、現在の環境の環境変数名を列挙します。

また、FOR 変数参照の置換も拡張されました。
次のオプション構文を使うことができます:

    %~I         - すべての引用句 (") を削除して、%I を展開します。
    %~fI        - %I を完全修飾パス名に展開します。
    %~dI        - %I をドライブ文字だけに展開します。
    %~pI        - %I をパス名だけに展開します。
    %~nI        - %I をファイル名だけに展開します。
    %~xI        - %I をファイル拡張子だけに展開します。
    %~sI        - 展開されたパスは短い名前だけを含みます。
    %~aI        - %I をファイルの属性に展開します。
    %~tI        - %I ファイルの日付/時刻に展開します。
    %~zI        - %I ファイルのサイズに展開します。
    %~$PATH:I   - PATH 環境変数に指定されているディレクトリを
                   検索し、最初に見つかった完全修飾名に %I を
                   展開します。
                   環境変数名が定義されていない場合、または検索
                   してもファイルが見つからなかった場合は、この
                   修飾子を指定すると空の文字列に展開されます。

修飾子を組み合わせて、複合結果を得ることもできます:

    %~dpI       - %I をドライブ文字とパスだけに展開します。
    %~nxI       - %I をファイル名と拡張子だけに展開します。
    %~fsI       - %I を完全なパスと短い名前だけに展開します。
    %~dp$PATH:I - PATH 環境変数に指定されているディレクトリを
                   検索して %I を探し、最初に見つかったファイル
                   のドライブ文字とパスだけに展開します。
    %~ftzaI     - %I を DIR コマンドの出力行のように展開します。

上の例の %I と PATH は、他の有効な値で置き換えることができます。
%~ 構文は、有効な FOR 変数名によって区切られます。%I のような大
文字の変数を使うと読み取りやすく、大文字と小文字を区別しない修飾子
との混乱を避けることができます。

for文の種類

HELPが若干見づらいのでまとめます。

for文の種類の一覧

FOR %変数 IN (セット) DO コマンド [コマンドパラメーター]
FOR /D %変数 IN (セット) DO コマンド [コマンド パラメーター]
FOR /R [[ドライブ:]パス] %変数 IN (セット) DO コマンド [コマンド パラメーター]
FOR /L %変数 IN (開始,ステップ,終了) DO コマンド [コマンド パラメーター]
FOR /F ["オプション"] %変数 IN (ファイル セット) DO コマンド [コマンド パラメーター]
FOR /F ["オプション"] %変数 IN ("文字列") DO コマンド [コマンド パラメーター]
FOR /F ["オプション"] %変数 IN ('コマンド') DO コマンド [コマンド パラメーター]
FOR /F ["usebackq オプション"] %変数 IN (ファイル セット) DO コマンド [コマンド パラメーター]
FOR /F ["usebackq オプション"] %変数 IN ('文字列') DO コマンド [コマンド パラメーター]
FOR /F ["usebackq オプション"] %変数 IN (`コマンド`) DO コマンド [コマンド パラメーター]

詳細はHELP本体をよく読むべし。

個人的によく使うオプションは、オプションなし・/Lオプション・/Fの"usebackq"付きのオプションの3種類です。
/Fオプションはややこしいですが便利なのでよく読んで使いこなしましょう!

「%変数」の展開について

この部分の記述

また、FOR 変数参照の置換も拡張されました。
次のオプション構文を使うことができます:

    %~I         - すべての引用句 (") を削除して、%I を展開します。
    %~fI        - %I を完全修飾パス名に展開します。
    %~dI        - %I をドライブ文字だけに展開します。
    %~pI        - %I をパス名だけに展開します。
    %~nI        - %I をファイル名だけに展開します。
    %~xI        - %I をファイル拡張子だけに展開します。
    %~sI        - 展開されたパスは短い名前だけを含みます。
    %~aI        - %I をファイルの属性に展開します。
    %~tI        - %I ファイルの日付/時刻に展開します。
    %~zI        - %I ファイルのサイズに展開します。
    %~$PATH:I   - PATH 環境変数に指定されているディレクトリを
                   検索し、最初に見つかった完全修飾名に %I を
                   展開します。
                   環境変数名が定義されていない場合、または検索
                   してもファイルが見つからなかった場合は、この
                   修飾子を指定すると空の文字列に展開されます。

修飾子を組み合わせて、複合結果を得ることもできます:

    %~dpI       - %I をドライブ文字とパスだけに展開します。
    %~nxI       - %I をファイル名と拡張子だけに展開します。
    %~fsI       - %I を完全なパスと短い名前だけに展開します。
    %~dp$PATH:I - PATH 環境変数に指定されているディレクトリを
                   検索して %I を探し、最初に見つかったファイル
                   のドライブ文字とパスだけに展開します。
    %~ftzaI     - %I を DIR コマンドの出力行のように展開します。

上の例の %I と PATH は、他の有効な値で置き換えることができます。
%~ 構文は、有効な FOR 変数名によって区切られます。%I のような大
文字の変数を使うと読み取りやすく、大文字と小文字を区別しない修飾子
との混乱を避けることができます。

ですが、for文で使用する「%変数」は、上記のように部分展開することが可能です。(BATファイルで使用するときは「%%変数」)
call /?にも同じことが書いてありますが、%1などと同じように展開が可能です。

よく使うのは

  • 「%%~dpI」…絶対パスで、フォルダまで展開
  • 「%%~nI」…拡張子を除くファイル名に展開

のあたりですかね。