まくまく Windows ノート
バッチファイルの FOR ループ (2) テキストファイル、コマンド出力を 1 行ずつループ処理
2015-11-09

テキストファイルを一行ずつ処理する

FOR コマンドに、/F オプションを指定すると、指定したテキストファイル内の各行をループで処理することができます。 ここでは、入力データとして、下記のようなテキストファイルを使用します。

data.txt

A1 A2 A3 A4 A5
B1 B2 B3 B4 B5
C1 C2 C3 C4 C5

次のバッチファイルは、data.txt の内容を一行ずつループで取得して表示しています。

sample.bat

@echo off
FOR /F %%A IN (data.txt) DO echo %%A

実行結果

A1
B1
C1

あれ???各行が 1 単語ずつしか表示されませんね。 これは、FOR /F コマンドが、デフォルトでは スペースやタブ をデリミタとして、各フィールドを区切って変数に格納するからです。 一行全体を %%A に取得するには、下記のようにデリミタ文字を delims= オプションで無効にしてしまうか、tokens=* としてすべてのフィールドをまとめて取得します。

sample.bat

FOR /F "delims=" %%A IN (data.txt) DO echo %%A
FOR /F "tokens=*" %%A IN (data.txt) DO echo %%A

実行結果

A1 A2 A3 A4 A5
B1 B2 B3 B4 B5
C1 C2 C3 C4 C5

デリミタで区切られた各フィールドの値を %%A%%B%%C%%D%%E というそれぞれの変数に取得したい場合は、下記のように tokens オプションを指定します。

sample.bat

FOR /F "tokens=1-5" %%A IN (data.txt) DO echo %%A %%B %%C %%D %%E

実行結果

A1 A2 A3 A4 A5
B1 B2 B3 B4 B5
C1 C2 C3 C4 C5

上記では、1 番目から 5 番目のフィールドを取得するように tokens=1-5 と指定していますが、tokens=2,3 のように、任意の位置のフィールドのみを抜き出すこともできます。

sample.bat

FOR /F "tokens=2,3" %%A IN (data.txt) DO echo %%A %%B

実行結果

A2 A3
B2 B3
C2 C3

なお、tokens オプションで指定したフィールド番号の順序は、実行結果に影響しません。 例えば、tokens=3,2 と番号を逆順で指定しても、%%A には 2 番目のフィールドの値(A2 など)が格納されます。

スペースを含んだファイル名を指定する場合の注意

FOR /F コマンドの集合に、ダブルクォーテーション " で囲まれた文字列を渡すと、その文字列そのものがパースされます(ファイル名とはみなされない)。

FOR /F "tokens=1,3" %%A IN ("aaa bbb ccc") DO echo %%A %%B

実行結果

aaa ccc

この仕様のおかげで、スペースを含んだファイル名を指定することが難しくなっています。 例えば、read me.txt というファイル名を指定したとします。

FOR /F "tokens=1" %%A IN ("read me.txt") DO echo %%A

上記の結果は、read と表示されて終わりです。 これは、read me.txt という文字列がダブルクォーテーション " で囲まれているため、それがテキストデータそのものだと判断されているからです。 この振る舞いを抑制し、ファイル名だと判断させるには、下記のように usebackq オプションを指定します。

FOR /F "tokens=1 usebackq" %%A IN ("read me.txt") DO echo %%A

コマンドの出力を一行ずつ処理する

FOR /F コマンドでは、テキストファイルの中身を処理するだけではなく、任意のコマンドの出力結果を扱うことができます。

下記のバッチファイルは、環境変数の一覧を表示する set コマンドの出力を FOR /F ループで一行ずつ処理しています。 デリミタを = と設定し、1 番目のフィールドを指定することによって、環境変数名だけを抽出しています。

vars.bat

@echo off
FOR /F "delims== tokens=1" %%A IN ('set') DO echo %%A

実行例

C:\> vars
...
NUMBER_OF_PROCESSORS
OS
Path
PATHEXT
PROCESSOR_ARCHITECTURE
PROCESSOR_IDENTIFIER
PROCESSOR_LEVEL
...
2015-11-09