今日は、for コマンドの /f スイッチをやろう。

/f スイッチは非常に特殊で、
テキストファイルの内容や文字列、
そしてコマンドの実行結果に対して、
一行ずつ繰り返しを実行することができる。

構文は以下の通り。

「for /f "オプション" 変数 in (対象) do 繰り返しコマンド」

オプションは後で説明するが、
とりあえず usebackq と記入すると覚えておけばいい。

対象には、ファイルを処理する場合はファイルのパスが入る。
パスはスペースで区切って複数並べる事ができる。
パスがスペースを含む場合は、パスをダブルクォートで囲む。

C:\>for /f "usebackq" %f in ("boot.ini") do @echo # %f
# [boot
# timeout=5
# default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
# [operating
# multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft
# C:\CMDCONS\BOOTSECT.DAT="Microsoft

ここでは、boot.ini の内容を書き出したが、
%f には一部しか入っていない。

実は、for コマンドは、行をトークンに分解する機能を持つ
これらはオプションで指定できるのだ。

例えば、netstat の出力結果を CSV に整形してみよう。
通常、netstat -a は以下のような出力である。

C:\>netstat -a

Active Connections

  Proto  Local Address          Foreign Address        State
  TCP    computer:epmap        computer:0            LISTENING
  TCP    computer:1686          pop.local.com:pop3    TIME_WAIT

これを整形するためにはオプションを使う。

取り出したい項目はプロトコル、ローカル IP、
リモート IP、状態の 4 つであるので、
tokens=1-4 を指定する。

そして各項目を区切る文字はスペースである。
for は既定で、複数のスペースを区切りとして認識する。

先頭にある、「Proto ~」のヘッダ行は、
Local Address など、スペースが含まれているので、
内容と同じ方法では分解できないため、
単純に無視する方法で考えよう。
それには、skip=4 を指定して、先頭 4 行を読み飛ばす。

コマンドの出力結果を使う場合は、
対象に、バッククォートでくくって指定する。

for /f "usebackq tokens=1-4 skip=4" %f in (`netstat -a`)

tokens= を指定した場合は、
分解結果は、複数の変数に格納される
この場合、for 文に指定した文字から順番となる
アルファベットの文字の変数が自動的に割り当てられる。
今回の場合、%f, %g, %h, %i の 4 変数に分解される。

C:>for /f "usebackq tokens=1-4 skip=4" %f in (`netstat -a`) do @echo "%f","%g","%h","%i"
"TCP","computer:epmap","computer:0","LISTENING"
"TCP","computer:1686","pop.local.com:pop3","TIME_WAIT"

for はテキスト処理に欠かせないコマンドだ。