2013年3月11日月曜日

@setlocal EnableDelayedExpansionの使い方

@setlocal EnableDelayedExpansionの使い方について


はじめに:

EnableDelayedExpansionは遅延環境変数を使用可能にするオプションです。
この設定が欲しくなるケースは恐らくその多くの場合、「For loop内で、loopが1巡する毎に異なる値を環境変数に設定したい時」だと思います。

以下説明は、「setlocal /?」と「cmd /?」のヘルプからの引用+自分なりに解釈した、環境変数遅延環境変数の違いです(たぶん合ってる、間違っていたらすみません。。。)

  • 環境変数は区切り文字として % を使います (例:%var%)
  • 遅延環境変数は区切り文字として ! を使います (例:!var!)
  • 環境変数はforループ中に値を変更することができません。forループが完了してからループ中最後に代入された値が入ります(途中で代入された値は無視されます)。 同様にLoopに入る前にすでに環境変数に値が入っている場合はLoop中は常にその値が維持されます、そしてLoopが完了した時点でLoop中最後に代入された値が反映されます。
  • 遅延環境変数はforループ中にsetで値を代入することができます。(<-- これが、いいですねー)

と、いきなり言われても結局どう使えるの?
ということで、遅延環境変数の使用例です



使用例:

ある複数行のテキストファイルがあり、For分で一行ずつ環境変数に読み込んでEchoでその環境変数を標準出力する。

手順:

  1. C:\temp\forというフォルダを作成
  2. EnableDE.bat(*1)をC:\temp\forに作成
  3. readFile.txt(*2)というファイルを準備(内容はなんでもいいんです)
  4. CMDを開いてC:\temp\forに移動(cdする)
  5. EnableDE.batを実行
5の実行結果、下のような結果が出てくれば成功です(!count!には行番号、!readline!は各行の文字列になります)

C:\Temp\for>EnableDE.bat
Line:1 This is a sample file to be read
Line:2 by "for" statement in test.bat.
Line:3 Each line to be set as a value
Line:4 of the environment varialble,
Line:5 "!readline!" and shown
Line:6 by echo !readline!.
Line:7 This requires
Line:8 "@setlocal EnableDelayedExpansion"
Line:9 enables setting each line to
Line:10 !readline! variable
Line:11 *EVEN* that's set sometime in "for" loop
Line:12 As default, otherwise, setting
Line:13 several values in a "for" loop
Line:14 wasn't allowed.




(*1)EnableDE.bat

=========================================
@echo off
@setlocal EnableDelayedExpansion
set count=
for /f "delims=" %%s in (C:\temp\for\readFile.txt) do (
 set /a COUNT+=1
 set readline=%%s
 echo Line^:!count! !readline!
)


(*2)readFile.txt

=========================================
 This is a sample file to be read
 by "for" statement in test.bat.

 Each line to be set as a value
 of the environment varialble,
 "^!readline^!" and shown
 by echo ^!readline^!.

 This requires
 "@setlocal EnableDelayedExpansion"
 enables setting each line to
 ^!readline^! variable
 *EVEN* that's set sometime in "for" loop
 As default, otherwise, setting
 several values in a "for" loop
 wasn't allowed.

ちなみに:

一方で、環境変数を使った場合はForループ内で値は変更されないことが分かります
気になる方は、DisabledDE.batをC:\temp\forで実行してみください

(*3)DisabledDE.bat

=========================================
 @echo off
set count=
for /f "delims=" %%s in (C:\temp\for\readFile.txt) do (
 set /a COUNT+=1
 set readline=%%s
 echo Line^:%count% %readline%
)

0 件のコメント:

コメントを投稿