FOR コマンドに、/F
オプションを指定すると、指定したテキストファイル内の各行をループで処理することができます。
ここでは、入力データとして、下記のようなテキストファイルを使用します。
A1 A2 A3 A4 A5
B1 B2 B3 B4 B5
C1 C2 C3 C4 C5
次のバッチファイルは、data.txt
の内容を一行ずつループで取得して表示しています。
@echo off
FOR /F %%A IN (data.txt) DO echo %%A
A1
B1
C1
あれ???各行が 1 単語ずつしか表示されませんね。
これは、FOR /F
コマンドが、デフォルトでは スペースやタブ をデリミタとして、各フィールドを区切って変数に格納するからです。
一行全体を %%A
に取得するには、下記のようにデリミタ文字を delims=
オプションで無効にしてしまうか、tokens=*
としてすべてのフィールドをまとめて取得します。
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
オプションを指定します。
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
のように、任意の位置のフィールドのみを抜き出すこともできます。
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 番目のフィールドを指定することによって、環境変数名だけを抽出しています。
@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
...