treedown’s Report

システム管理者に巻き起こる様々な事象を読者の貴方へ報告するブログです。会社でも家庭でも"システム"に携わるすべての方の共感を目指しています。

※https化しました。その影響でしばらくリンク切れなどがあるかもしれませんが徐々に修正していきます。 リンク切れなどのお気づきの点がございましたらコメントなどでご指摘いただけますと助かります。

バッチファイルのfor命令を学ぶサンプルバッチファイル

前回「Windowsバージョン情報をレジストリから取得してみる」でサンプルバッチファイル内でfor文を使っていましたが、for文を深掘りしたことがなかったので、使ったことがある内容をご報告です。

for文は繰り返し実行

バッチファイルじゃなくても基本的なプログラムを学ぶと繰り返し処理を実行する際にfor文はよく出てきます。

バッチファイルにおけるfor文は、バッチ内でコマンドを繰り返し実行するために使われることが多い命令です。繰り返しの制御に一時変数を使用します。

書式

本ブログで使ったことのあるfor文の書式は以下のようになります。
※コマンドプロンプトで「for /?」から参照。

for [オプション] %%[変数名] in [セット] do [コマンド] [コマンドパラメータ]


[オプション]は、「/F」しか使ったことがないのですが、他にも「/D」や「/R」や「/L」があります。詳しくはヘルプで確認を。

%%[変数名]は、「%%i」とか「%%a」を使います。指定した文字から順番に使えます。(例:「%%i」なら「%%j」「%%k」と言う具合に、「%%a」なら「%%b」「%%c」という具合に。

[セット]は、データソースの記述箇所になります。ファイル内のデータを探すなら「○○.txt」のようにファイル名を指定しますし、コマンドの実行結果から探す場合には「dir /b」のような実行するコマンドを記述します。

[コマンド] [コマンドパラメータ]は、for文を実行した結果のアウトプットとして実行させたいコマンドを実行します。よく使うバッチファイルでは主に「set」コマンドで値を収集することが多いです。

ちなみに、バッチファイル内で使う場合の一時変数の書式は「%%i」のように「%%」としますが、コマンドプロンプトで使う場合には一時変数の書式は「%i」となります。大文字と小文字は違う変数名として認識します。

サンプルバッチファイル-1

前回「Windowsバージョン情報をレジストリから取得してみる」のサンプルバッチファイルを例として、for文の部分を確認してみます。

--------------------------------------------------------------
Winver-test.bat
--------------------------------------------------------------
@echo off
set WinDispVer=

for /F "tokens=3" %%i in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v "DisplayVersion"') do set WinDispVer=%%i

echo %WinDispVer%

set WinDispVer=
--------------------------------------------------------------

ここのfor文では
「reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v "DisplayVersion"」
の実行結果を、変数%WinDispVer%に代入するという処理を実行しています。

ただ、コマンドの実行結果を単純に代入すると余分な文字列や改行などが含まれた状態で代入されてしまい、正常に取得したい情報を変数に代入することができませんでした。

※単純に実行結果「DisplayVersion    REG_SZ    23H2」を変数に代入すると先頭の「DisplayVersion」だけが変数に保存され、その後ろの「REG_SZ」や「23H2」は切り捨てられてしまいます。

コマンドの実行結果から収集したい情報を指定するための命令が、for文内の「"tokens=3"」の部分で指定されています。デフォルトでスペース区切りのデータのうち、左から何番目のデータを保管するか指定できる命令で、「"tokens=3"」では左から三番目を変数への代入対象としています。

※図はバッチファイルでなく、for文をコマンドプロンプトで単体実行しています。

例えば、「"tokens=2"」とすれば二番目の表示である「REG_SZ」が保管されますし、省略したデフォルトと同じ「"tokens=1"」は「DisplayVersion」という文字列が保管されます。

今回欲しかったのは値のデータである「23H2」なので、for文には"tokens=3"オプションを付加して実行されたコマンドの結果出力から欲しい情報を変数%WinDispVer%に保管できています。

サンプルバッチファイル-2

もうちょっと手の込んだバッチで確認してみましょう。

日付を取得して、年/月/日をそれぞれ異なる変数に代入する、というサンプルバッチファイルです。

--------------------------------------------------------------
DaySplit.bat
--------------------------------------------------------------

@echo off
set todayis=%date:/=-%
set Year=
set month=
set day=

echo "-"区切りの日付表記です。
echo %todayis%

echo "-"区切りを別々の変数に代入していきます。

FOR /F "delims=- tokens=1,2,3" %%i in ("%todayis%") DO (
        set Year=%%i
        set month=%%j
        set day=%%k
        )

echo 今年は、%Year% 年
echo 今月は、%month% 月
echo 今日は、%day% 日

set todayis=
set Year=
set month=
set day=

--------------------------------------------------------------

このバッチでは、システム環境変数%date%からバッチファイル実行時点である今日の日付を取得して、変数%todayis%に代入し、その変数の中に入っている文字列をfor文で分解するという処理を実施しています。

実行すると、

このように最初の「echo %todayis%」で今日の日付を表示しますが、その後、それぞれ年月日を分割して表示するようにしています。

この際に使っているのが、for文内の「"delims=- tokens=1,2,3"」という指定です。「in ("%todayis%")」にあるデータソースからそれぞれ「delims」で指定した区切り文字「-」をデータの境界として、左から一番目のデータ(最初のデータ)を変数%Year%に、左から二番目のデータ(一時変数%%jのデータ)は変数%month%に、左から三番目のデータ(一時変数%%kのデータ)は変数%day%にそれぞれsetコマンドで代入しています。

このようにfor文内では区切り文字を指定することで、変数内やファイル内に格納されているデータを分解して、それぞれを独立して取り扱うこともできます。

ちょっとしたTIPSですが、システム環境変数%date%はデフォルトの区切り文字「/」を変更することができます。

今回は「/」を「-」に置き換えました。その場合の標記は「%date:/=-%」と標記します。

for文は奥が深い

今回、これまでの本ブログで使ったことのあるfor文の使い方を改めて解説してみましたが、まだまだ解説し切れていない内容がfor文にはあります。ちょっと手の込んだバッチファイルを作る時にfor文を使うとできることの幅が広がるので、バッチファイル作成者には「for /?」でコマンドの説明に一通り目を通して欲しいと思います。