DOSでbatプログラムをちゃちゃっと作るはずだったのですが、見事にハマったのでメモ。
(未だにDOSを使わざるをえないのです。)
やりたかったこと
For文の中で変数をインクリメントしたい。
最初のコード
こんな感じで動くでしょ?
@echo off set /A num=0 FOR %%i IN (hoge huga hugo) DO ( set /A num=num+1 @echo %num% )
出力結果は……
0 0 0
なぜ??
ポイントは「環境変数の展開タイミング」にある
batプログラムは、実行時ではなくプログラム1行ごとのの読込み時に変数を展開します。
前述のFORは、
FOR %%i IN (hoge huga hugo) DO ( set /A num=num+1 @echo %num% )
で1行です。
そのため上記のプログラムは、FOR文を読み込んだ段階で次のように変数を展開してから実行されます。
FOR %%i IN (hoge huga hugo) DO ( set /A num=num+1 @echo 0 )
アンビリーバボーですね!まさかの展開ですね!
ちなみにこれを「環境変数の即時展開」と呼びます。
「環境変数の遅延展開」が答え!
この「即時展開」を「遅延展開」する、つまりプログラム実行時に変数を展開することで、問題を解決できます。
遅延展開を行うには2つのプロセスが必要です。
1.setlocal enabledelayedexpansion で遅延の展開を有効にする
batプログラムの冒頭で次の宣言を行います。
setlocal enabledelayedexpansion
これにより「遅延展開」を有効化します。
2.!変数!で遅延展開を実施する。
遅延展開を行う変数は、通常の変数(%変数%)と宣言方法が異なります。
「%」ではなく「!」(エクスクラメーション)で変数を囲むことで、「その変数は遅延展開するんだよ」という意味合いになります。
最終的なコード
@echo off setlocal enabledelayedexpansion set /A num=0 FOR %%i IN (hoge huga hugo) DO ( set /A num=num+1 @echo !num! )
出力結果は……
1 2 3
やりました!!
参考にさせていただきました
こちらのサイトに詳しく紹介されています。
http://wa3.i-3-i.info/word12518.html
[改訂新版]Windowsコマンドプロンプトポケットリファレンス
- 作者: 山近慶一
- 出版社/メーカー: 技術評論社
- 発売日: 2016/03/04
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る
- 作者: 飯島弘文
- 出版社/メーカー: 翔泳社
- 発売日: 2003/08/23
- メディア: 単行本(ソフトカバー)
- 購入: 3人 クリック: 100回
- この商品を含むブログ (16件) を見る