関連記事
やりたいこと
各種コマンドを使って取ってきた情報から、1行丸ごとではなく、必要な情報というか要素だけ取り出したい。
例えば、以前試したdir
で一覧として出るファイル・フォルダからfind
でいるものだけ絞ったあと、そのファイル・フォルダの更新時間を取り出したい、などの場合。(下記のイメージ)
やり方
for
文を使う。
forの原型
for [オプション] %%アルファベット1文字 in (ループの対象) do (
処理
)
この中の「ループの対象」には、例えばdirなどのコマンドを入れることができる。
そのコマンドの結果が「%%アルファベット1文字」に入るイメージ。
(forといえばループだが、ループのためではなく「コマンドの戻り値を採る」ために使う)
具体的な例
今回は、dirで取得したファイル・フォルダ一覧から「target.txt」の行を取り出し、その中から時間の文字列を取り出す、ということをする。下記のバッチで取り出せる。
@echo off
FOR /F "tokens=2" %%A IN ('dir ^| find "target.txt"') DO (
ECHO update time is %%A
)
pause
update time is 22:09
説明
トークン
for
のオプション/f
には、「トークン」というものを指定できる。
トークンには、下記のようなものがある。参考
- tokens= 何番目のトークンを指定するか?
- delims= トークンの区切り文字を指定
- eol= この文字から始まる行を無視
- skip= 先頭から指定された行数、スキップする。
- usebackq コマンドの出力を対象にする
その中のtokens
を使用する。
tokens
tokens
に2を指定すると、「スペースで区切られた文字列の2番目のものをとって、%%Aに入れる」という意味になる。
上の例だと、dir ^| find "target.txt"
でとってきた1行の文字列の、スペース区切りの2番目を採ることになる。
ループの対象(=コマンド)
下記のかっこの中には、戻り値を取得したいコマンドを書く。
FOR /F "tokens=2" %%A IN ('dir ^| find "target.txt"') DO (
※注意
forの中で、パイプを使ってdir
→find
とデータを渡したいときには、「|」の横に「^」をつけないと動かなかった。(普通は「|」だけでよく、^はいらない)
処理
コマンドの結果が%%A
に入ってくるので、それを使った処理を書く。
この場合は、%%Aに時間の文字列が入ってくる。
ECHO update time is %%A
実際にこれを使ったとき
実際には、下記のような場面でこの方法を使った。
- diskpartで、ボリュームの一覧を取得
- その中で「MYVOLUME」というラベル名のボリュームを探す。
- そのボリュームに「T]というドライブ?レターを付与する
- そのドライブ(Tドライブ)に移動(cd)する
@echo off
ECHO list volume > %~dp0listvolume.txt
diskpart /s %~dp0listvolume.txt
FOR /F "tokens=2" %%A IN ('diskpart /s %~dp0listvolume.txt ^| find "MYVOLUME"') DO (
ECHO select volume=%%A > %~dp0selectvolume.txt
)
ECHO assign letter=T > %~dp0selectvolume.txt
del %~dp0selectvolume.txt
del %~dp0listvolume.txt
cd /d T:
pause
※各コマンド(diskpartなど)については割愛。
※diskpartでラベル名とそのボリューム番号は取れてるのに、ボリューム番号だけ取得できるような便利機能がなかったため、この方法で取得した。
※diskpartでは下記のようなデータが取れるので、その中の「Volume 0」の「0」だけ取りたかったイメージ。(図は上のサンプルと別環境なので「MYVOLUME」はない)
参考
.bat(バッチファイル)のforコマンド解説。
https://qiita.com/sawa_tsuka/items/67be34bab1fdf3fb87f9
→この記事さえ見ればすべてわかる感じです。