新人ぷろぐらまの覚え書き

最近プログラマーに転職したアザラシのブログ。

変数の即時展開で詰まった話

バッチの文法の勉強をしようと思い、簡単な処理のバッチを作成していたのですが

for文で文字列をループ処理で結合しようとして「変数の値が消える」という現象に悩まされたので調べたことをメモっておきます。

 

・やろうとしたこと

ディレクトリ内のファイル名を取得してテキストファイルに書き出すバッチを作りたい。

 

・困ったところ

for文でループ中に、取得したファイル名を変数に結合したかったのだが、

最終ループで取得したファイル名しか変数に入っていない!という現象が発生…。

 

この時点で書いていたもの↓

set name=
for %%i in (*.xlsx) do (

echo ファイル名:%%i

set name=%name% %%i)

echo %name%>names.txt

exit

 

 カレントディレクトリに1.xlsxと2.xlsxというエクセルファイルが存在していた場合、

names.txtに

 1.xlsx 2.xlsx

 と表示されるはずが、

 2.xlsx

しか表示されない!なんでや!

 

調べたところ、これは「変数の即時展開」によるものらしく、

変数の中身はその行を読み込んだときに値に置き換わるため、

ループの中で%name%が先に評価されるためにこうなってしまうみたい。

実行中に値を変化させたい場合は

setlocal enabledelayedexpansion (遅延環境変数)を宣言しないといけないらしい。

 

setlocalを宣言した時の文法のルール

・setlocal enabledelayedexpansionで宣言、終了時に「endlocal」

・実行中に値を変化させたい変数を使う(評価する)時に!で囲う

 

ということでsetlocalを宣言してバッチを修正↓

setlocal enabledelayedexpansion
set name=
for %%i in (*.xlsx) do (
set name=!name! %%i
)
echo %name%>names.txt
endlocal

 

これを実行すると

 1.xlsx 2.xlsx 

 と表示されました。ヤッタネ!

 

まぁこの処理やるなら↓でいいんですけど・・・

dir ファイル名を調べたいファイルパス\*.xlsx /b >ファイル名.txt

 

 

なかなかバッチの文法に慣れないな~~

あと何個か簡単なものを書いてみて覚えていきたいと思います・・・