Windows - バッチ - ループ変数・制御

 クラウディア
1. 概要
2. ループ内の変数の不思議
3. ループ内の変数の書き方
4. continue 的な動作

1. 概要

 バッチファイルの、ループは、簡単なようで、なかなか、要領が必要です。  制御に関しては、下記のサイトを参考にさせていただきました。
バッチファイルのループのスキップについて Windows バッチで、J...

2. ループ内の変数の不思議

 前ページに書いたように

BBB
CCC
DDD
 という内容の 「AAA.txt」 があるとして

@ECHO  OFF

FOR /F %%A IN (AAA.txt) DO (
    ECHO %%A
)
 というバッチファイルを実行すると

BBB
CCC
DDD
 という実行結果が得られるわけです。  ではこの 「%%A」 を変数に入れて出力しようと

@ECHO  OFF

FOR /F %%A IN (AAA.txt) DO (
    SET B=%%A
    ECHO %B%
)

ECHO %B%
 というバッチファイルを書いて実行すると

ECHO は <OFF> です。
ECHO は <OFF> です。
ECHO は <OFF> です。
DDD
 という実行結果になるのです。

    ECHO %B%
 は

    ECHO
 と書いているのと同じ効果しか得られません。  つまり、「%B%」 は変数展開されていないのです。

3. ループ内の変数の書き方

 結論から書くと

@ECHO  OFF
SETLOCAL ENABLEDELAYEDEXPANSION

FOR /F %%A IN (AAA.txt) DO (
    SET B=%%A
    ECHO !B!
)

ECHO %B%
 と書くと結果は

BBB
CCC
DDD
DDD
 となります。  2行目の

SETLOCAL ENABLEDELAYEDEXPANSION
 は、ループ内の変数を有効化するためのおまじないです。  6行目の

    ECHO !B!
 は、ループ内では変数を 「%B%」 のように書くのではなく 「!B!」 のように記述するということです。

4. continue 的な動作

 いわゆる、「C 言語」では、ループ処理内で、「continue;」という制御を行えば、ループのカウンタを次へ移行しつつ、処理の先頭へ戻ります。  バッチファイルでは、明示的にそのような予約語は、ありません。  参考サイトの方法で、「CALL」「GOTO」を使うことで、それらしい制御ができましたので、記録しておきます。  サンプル的に書いてみますと・・・。

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

FOR /L %%I IN (1, 1, 3) DO (

    SET NUM=%%I
    CALL :SUB
)

PAUSE
EXIT

:SUB
IF !NUM! EQU 2 (GOTO SKIP)

ECHO !NUM!

:SKIP
 4行目は、1 を初期値で、1ずつインクリメントで 3 までなので、1、2、3 が「%%I」にはいります。  6行目は、「%%I」が、下までスコープされないので、「NUM」という変数に入れています。  14行で、1、3 だけ処理して、2 は「continue」させるために、「GOTO」で「SKIP」というラベルにとびます。  これで、2 を「continue」させる制御ができるわけです。
5G CONNECT