Hatena::ブログ(Diary)

演算記録 このページをアンテナに追加 RSSフィード

Subscribe with livedoor Reader Subscribe with Fastladder

2007-12-06 【Lifehacks】バッチスクリプトのFor文を活用する02 このエントリーを含むブックマーク このエントリーのブックマークコメント

■概要

 バッチスクリプトのFor文を活用する。


■説明

 「バッチスクリプトのFor文を活用する01」(http://d.hatena.ne.jp/Orihika/20071203)で示した例では、For文の実行部はechoコマンド一つからなっていました。

 これはバッチスクリプトのFor文の制限で、多くのプログラミング言語のように実行部を複数行からなるブロックにすることができません。

 しかし以下のような手法を使えば、それに近いコードを書くことができ可読性を向上させられます。


■要素技術

・For文の実行部にCall命令を記述

 For文では、do以下に実際に実行するコマンドを記述します。

 一般的なスクリプト言語と異なり実行部を複数行に記述するなど複雑な指定ができないため、Call命令を使用しプロシージャ呼び出しを行います。


・Callによるファイル内プロシージャ呼び出し

 Call命令の引数の先頭が「:」で始まる文字列の場合、同じバッチスクリプト内のラベル以下をプロシージャとして呼び出します。

 当該プロシージャは別プロセスではなく、元のバッチスクリプトと同じプロセスで動作します。

 処理の流れは、まず指定ラベルまでジャンプしスクリプトの末尾まで進んだ後、呼び出し元位置の次の行に戻ります。

 お約束としてプロシージャの末尾に「goto :EOF」を記述することで、同じバッチスクリプトファイル内に複数のプロシージャを定義することができます。

・プロシージャをFor文の実行部に見せかけるコーディング

 Call命令で呼び出すプロシージャはバッチスクリプトの任意の場所に書けますが、For文の実行部に相当するコードはFor文の直後に書いた方がわかりやすくなります。

 その際、お約束として以下のコーディングを行います。

 - For文の実行部に相当するプロシージャの次の行にラベルを定義する。

  →下記例では「:End_Of_For01」

 - For文の次の行にそのラベルへのgoto文を書く。

  →下記例では「goto End_Of_For01」


:
: SgForSample02.bat
: バッチスクリプトのFor文のサンプル。
: (データファイルの各行を処理する)
:
: Author: Orihika Ikuo
: Create: 2007.12.03
: Update: 2007.12.04
:

set Result=Result.txt
set DataList=DataList.txt

del %Result%

:For01
for /f %%i in (%DataList%) do call :SubRoutine01 %%i
  goto End_Of_For01
  :SubRoutine01
    echo %1 >> %Result%
  goto :EOF
:End_Of_For01

noromanbanoromanba 2011/01/15 07:47 はじめまして。
>一般的なスクリプト言語と異なり実行部を複数行に記述するなど複雑な指定ができないため
とありますが、for〜do の()囲いは使えませんか。

〜上略〜
for /f %%i in (%DataList%) do (
echo %%i>> %Result%
@echo %time% @rem Example Line
)

とすればサンプルでやりたいことが実現出来る気がしたのですが。

for内のcallで:SubRoutine01に飛んだ後、goto :EOFでcallが終わり、forの次のステップへ、
というのはかなりトリッキーな気がしますが。
この手法でなければ実現できない処理とはどういった物なんでしょう。

noromanbanoromanba 2011/01/15 08:06 書いてから思いましたが、NT以前のOSでの利用目的とかでしょうか。
環境が書かれていないので何とも…ですが。

Connection: close