連載
» 2000年12月07日 00時00分 UPDATE

Windows 2000 活用講座 Windows 2000 コマンドライン徹底活用:第5回 スクリプト入門(その3) (1/2)

今回は、スクリプト処理における繰り返し処理(ループ構造)と、環境変数、パラメータ の扱いについて解説する。

[塩田紳二,著]
Windows 2000 活用講座 Windows 2000 コマンドライン徹底活用
Windows Server Insider


「Windows 2000 活用講座 Windows 2000 コマンドライン徹底活用」のインデックス

連載目次


 前回は、gotoコマンドとラベルを使った制御の移行(分岐)について解説した。今回は繰り返し処理(ループ構造)と変数やパラメータの扱いについて見ていこう。まずは、いちばん簡単なループの形態として、forコマンドを使った、複数ファイルの一括処理について解説する。

繰り返し

 条件判断と並んで、プログラム中でよく使われる機能が「繰り返し構造(ループ)」である。これは、一連の手順を何回も繰り返して実行させるもので、通常は、この処理が1回終わるごとにその結果を調べて、繰り返しを終了するかどうかを判定する。例えば、いくつもあるファイルに対して同じ処理を行うような場合に、このループを使って実現する。また、この繰り返しを終了することを「脱出」ということがある。繰り返しは、gotoと条件判断(if)の組み合わせでも記述可能だが、専用のキーワードを使うことでプログラムの見通しがよくなるため、多くのコンピュータ言語では、繰り返しを表現するための独立した機能を持っている。

 ループにはいくつかのパターンがあり、

  • 脱出条件
    (1) 条件を満たすまでループするもの
    (2) 条件を満たしている間ループするもの
  • 脱出条件の位置
    (1) 脱出条件判断をループの最初で行うもの
    (2) 脱出条件判断をループの最後で行うもの
    (3) 脱出条件判断をループの途中で行うもの

と分類できる。脱出条件とは、ループを終了させるための条件で、通常は、変数などの比較を行う。このとき、プログラムの見通しをよくするために、条件を「満たすまで」(満たしていない間)、条件を「満たしている間」で別の予約語を使うことが多い。この2つは、条件の指定方法が逆になっているだけで、どちらのループ形式でも、同じ繰り返しが表現できる。

 もう1つ重要な点は、脱出条件の判定をどこで行うかである。これにより、最初から脱出条件が成立しているような場合に、最低でも1回ループを実行するかどうかという違いが生じる。このため、ループを記述する際には、この判定の位置を検討する必要がある。なお、(3)は、(2)の変形ともいえるし、後述する無限ループの途中に脱出条件が埋め込まれているとみることもできる。

 また、ループの特殊な形として、

  • 無限ループ
  • 計数ループ

というものがある。前者は、脱出条件が常に不成立となっているもので、そのままでは永遠にループを回り続ける。これだと問題がありそうな気がするが、通常は、プログラムの停止を外部から指定したり、ループ中に条件判断などを使ってループからの飛び出しを行ったりする。

 計数ループとは、変数(制御変数と呼ばれる)の値を増減しながらループを実行し、制御変数の値が指定した値になったときにループを終了するものである。この形式のループは、プログラム中で比較的頻繁に使われることが多いため、別に予約語などが定義されていることが多い。

 通常は、これらのパターンに応じたステートメントが用意されているのだが、Windows 2000のコマンドプロンプト・スクリプト中では、forによるループのみがコマンドとして定義されており、これ以外のパターンのループは、ifステートメントとgotoステートメントを使って記述しなければならない。これには、ifコマンドとgotoコマンドを利用するが、数値の計算などの機能がないコマンドプロンプト・スクリプトでは、実際には、このようなループを作ることはあまりない。多く使われるのは、これから説明するforコマンドによるループである。

 forコマンドは、

for %%代入変数名 in (代入値1 代入値2 代入値3……)do 実行文

というのが基本となる。「代入変数名」には、“%%”を先頭に付けたアルファベット1文字の名前を指定する。この変数は、環境変数とは別のもので、実行文の中でのみ有効な変数である。なお、このforコマンドをコマンドプロンプトから直接利用する場合には、“%%”ではなく“%”を使う。例えば、

for %i in (*.txt) do type %i

などとする。これは、カレント・ディレクトリにある、拡張子が.txtであるファイルをすべてタイプ(表示)するという指示である。

 また、この代入変数名は、大文字/小文字の区別があるため、実行文中で参照を行う場合には、forコマンドの直後で指定したものと同じ文字を使う必要がある。

 括弧内の部分には、変数に代入する値を列挙することになっており、複数の項目がある場合は文字列をスペースで区切って指定する。ここに“*”を指定したり、“?”を含んだ文字列を指定すると、カレント・ディレクトリにあるファイル名に対して、これらのワイルド・カード文字列が展開され、その結果が変数に代入される。

 “do”以下には、実行するコマンドを記述する。全体を括弧でくくることで複数のコマンドを記述することも可能だ。

 実環境においてこのforステートメントは、括弧の中にファイル名などを列挙して、そのそれぞれに対して同じ処理を行う場合に利用するのが一般的である。

 具体的な動作を見てみることにしよう。カレント・ディレクトリに次のようなファイルやディレクトリがあるとする。

C:\TEST>dir
 ドライブ C のボリューム ラベルは WIN2000 です
 ボリューム シリアル番号は 8488-0C94 です

C:\TEST のディレクトリ

2000/12/01  15:46        <DIR>          .
2000/12/01  15:46        <DIR>          ..
2000/12/01  15:46                    21 file01.txt
2000/12/01  15:46                    21 file02.txt
2000/12/01  15:46                    21 file03.txt
                3 個のファイル                   63 バイト
                2 個のディレクトリ      954,138,624 バイトの空き領域

 ここで各file01.txt〜file03.txtファイルには、自身のファイル名を表す文字列(例えばfile01.txtなら「This is file01.txt」)が格納されている。このディレクトリ(C:\TEST)内で以下のスクリプトを起動してみよう(スクリプト名は「C:\CMD\FORTEST01.BAT」とする)。なお先頭の「@echo off」は、実行中のコマンドを表示させないための設定である。これがないと、コマンドの各行の内容がいちいち表示されてしまうので、結果が見づらくなる。また「echo ------START------」は、引数(この場合は“------START------”)として指定された文字列を表示するためのものである。

ファイル:fortest01.bat

@echo off
echo ------START------
for %%i in (file01.txt file02.txt file03.txt) do type %%i
echo ------END--------

 この結果は、

C:\TEST>\cmd\fortest01
------START------
This is file01.txt
This is file02.txt
This is file03.txt
------END--------

のようになる。このように、括弧の中に列挙されているファイル名に対して順次typeコマンドが適用され、ファイルの内容が表示された。この場合のforコマンドの動作を1ステップずつ追跡すると次のようになる。

(1) 最初の要素(ここでは“file01.txt”)が取り出され変数iに代入される
(2) この状態で、do以下を評価する

 ここで、“type %%i”は、“type file01.txt”と展開される

(3) 評価したステートメントを実行する

“type file01.txt”が実行され、その内容が表示される

(4) 次の要素があるなら、要素を取り出して変数に代入し(2)へ戻る
(5) 要素がないなら、forステートメントを終了する。

 次に同じディレクトリで、次のプログラムを実行してみる。

ファイル:fortest02.bat

@echo off
echo ------START------
for %%i in (*) do type %%i
echo ------END--------

 この場合、括弧内の“*”は、カレント・ディレクトリのファイルすべてを表す。このため、結果は先ほどと同じく、

C:\TEST>\cmd\fortest02
------START------
This is file01.txt
This is file02.txt
This is file03.txt
------END--------

となる。結果はまったく同じであるが、最初の例では、処理対象のファイル名をすべて列挙しているのに対し、この方法では、カレント・ディレクトリにあるファイル名をまったく知らなくても実行が可能である点が異なる。

 もう1つ、最初の例の変形として、

@echo off
echo ------START------
for %%i in (01 02 03) do type File%%i.txt
echo ------END--------

としても、まったく同じ結果が得られる。これは、末尾のみが変化するファイル名に対して処理を行う場合に有効で、この場合、ファイル名そのものを指定しているわけではないので、もっと柔軟な処理が可能になる。例えば、以下のようにすれば、拡張子の変更などが可能だ。

for %%i in (01 02 03) do ren File%%i.txt Name%%i.doc

 これは、“File01.txt”というファイル名を“Name01.txt”などと変更するためのものである。

 また、

for %%i in (01 02 03) do ren File%%i.txt >>ADD.TXT

あるいは、

for %%i in (*) do type %%i >>ADD.TXT

とすることで、すべてのファイル内容を1つのファイル(この例ではADD.TXT)に結合できる。

 さて、Windows 2000のforコマンドでは、Windows 9xのforコマンドと比べて、いくつかの拡張オプションが用意されている。これを使うと、「ディレクトリ名だけを取り出す」、「指定したディレクトリからサブディレクトリを含めて再帰的に動作する」、「数値範囲を指定して動作する」などが可能になる。

 例えば“/d”オプションを使うと、括弧内に“*”や“?”が含まれている場合には、その対象がファイルではなくディレクトリとなる。

ファイル:fortest03.bat

@echo off
echo ------START------
for /d %%i in (*) do echo %%i
echo ------END--------

これは、カレント・ディレクトリにある、ディレクトリの一覧を表示するスクリプトである。これを次のようなディレクトリ上で実行してみるとする。

C:\TEST>tree /f
フォルダ パスの一覧:  ボリューム WIN2000
ボリューム シリアル番号は 0006FE80 8488:0C94 です
C:.
├─dir01
│  │  file01.txt
│  │
│  ├─subdir01
│  │      filesub01.txt
│  │
│  └─subdir02
│          filesub02.txt

├─dir02
│      file02.txt

└─dir03
        file03.txt
        
※これはtreeコマンドの出力結果。
dir* はディレクトリ、 file*.txt はファイルを表している。

 カレント・ディレクトリが「C:\TEST」ならば、次のように、3つのディレクトリが表示される。

C:\TEST>\cmd\fortest03
------START------
dir01
dir02
dir03
------END--------

 “/d”ではなく“/r”オプションを付けると、各ディレクトリを再帰的にたどり、それぞれのディレクトリでforコマンドを実行する。

ファイル:fortest04.bat

@echo off
echo ------START------
for /r %%i in (*) do type %%i
echo ------END--------

 さきほどのディレクトリでこれを実行すると、各ディレクトリにあるファイルをすべて再帰的に走査して、処理を行うことができる。

C:\TEST>\cmd\fortest04
------START------
This is file01.txt
This is filesub01.txt
This is filesub02.txt
This is file02.txt
This is file03.txt
------END--------

 さらに、“/d”と“/r”を両方指定して、ディレクトリを再帰的にすべて走査することも可能である。


       1|2 次のページへ

Copyright© 1999-2017 Digital Advantage Corp. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。