1. tera1707

    No comment

    tera1707
Changes in body
Source | HTML | Preview
@@ -1,117 +1,120 @@
+**もくじ**
+→https://qiita.com/tera1707/items/4fda73d86eded283ec4f
+
# やりたいこと
各種コマンドを使って取ってきた情報から、1行丸ごとではなく、必要な情報というか要素だけ取り出したい。
例えば、[以前](https://qiita.com/tera1707/items/e1a73f09ebc14fd2b5f8)試した`dir`で一覧として出るファイル・フォルダから`find`でいるものだけ絞ったあと、そのファイル・フォルダの更新時間を取り出したい、などの場合。(下記のイメージ)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/99425c34-6bd2-8402-eeac-93c0eaeb5bc9.png)
# やり方
`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
```
```output.txt
update time is 22:09
```
# 説明
### トークン
`for`のオプション`/f`には、「トークン」というものを指定できる。
トークンには、下記のようなものがある。[参考](https://qiita.com/sawa_tsuka/items/67be34bab1fdf3fb87f9#6for%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AE%E6%A7%8B%E6%96%87-f%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%82%92%E4%BB%A3%E5%85%A5%E3%81%99%E3%82%8B-)
- tokens= 何番目のトークンを指定するか?
- delims= トークンの区切り文字を指定
- eol= この文字から始まる行を無視
- skip= 先頭から指定された行数、スキップする。
- usebackq コマンドの出力を対象にする
その中の`tokens`を使用する。
### tokens
`tokens`に2を指定すると、「スペースで区切られた文字列の2番目のものをとって、%%Aに入れる」という意味になる。
上の例だと、`dir ^| find "target.txt"`でとってきた1行の文字列の、スペース区切りの2番目を採ることになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/d3a530af-f723-7d52-0dae-e7215b61adba.png)
### ループの対象(=コマンド)
下記のかっこの中には、戻り値を取得したいコマンドを書く。
```
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」はない)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/8b527a9a-fd3e-27bb-6b17-ad29a32c95db.png)
# 参考
.bat(バッチファイル)のforコマンド解説。
https://qiita.com/sawa_tsuka/items/67be34bab1fdf3fb87f9
→この記事さえ見ればすべてわかる感じです。