コマンド拡張機能によって強化された for コマンドについての話です。for の基本は次のとおりです。
for %変数 in (セット) do コマンド%変数のところはバッチファイルの中では%%変数としなければなりません。
for はセットの内容が順に変数にセットされ、do 以下のコマンドが実行されます。
このセットに二重引用符を使用した場合、変数の値に二重引用符がそのまま残るときと、二重引用符が消えてしまうときがあります。この点に気をつけないと、do 以下のコマンドで変数を使う場合に思わぬエラーとなります。
(1) セットの内容がファイル(フォルダ)名を直接に指定する場合は、二重引用符が残る
次のコマンドを実行してみてください。>for %I in ("C:\Program Files") do @echo %I変数Iには二重引用符が付いた値がセットされていることがわかります。なので、do 以下でこの変数を「"%I"」として参照すると、間違った処理をします。二重引用符を除去した値を取得したい場合は、「%~I」という形式で参照します。
"C:\Program Files"
>for %I in ("C:\Program Files") do @echo %~I
C:\Program Files
(2) セットの内容がワイルドカードである場合は、二重引用符が残らない
次のコマンドを実行してみてください。>for /d %I in ("C:\Program Files*") do @echo %Iオプション /d を付けるとワイルドカードでフォルダを検索できます。参照して得た値を見ると、変数Iには二重引用符が残っていません。なので、do 以下でこの変数をフォルダとして参照しようとするなら「"%I"」と二重引用符で括ってやらないといけません。ちなみに、ここで「%~I」という形式で参照しても(もともと二重引用符がないので)結果は同じです。
C:\Program Files
C:\Program Files (x86)
>for /d %I in ("C:\Program Files*") do @echo %~I
C:\Program Files
C:\Program Files (x86)
(1)と(2)の違いは、通常のセットの for はセットされた値をただ取り出して do 以下を繰り返すだけなのに対して、セットにワイルドカードを使った for はファイル(またはフォルダ)を実際に検索してその結果を変数にセットすることによるものなのでしょう。
しかし、同じ構文で変数の値に二重引用符が残る場合と残らない場合があるというのは直感的でなく、バッチファイルを書いているときに見落としがちで、思わぬエラーを引き起こすことになりやすいです。
対策としては、do 以下で変数を参照する形式は常に「%~I」として二重引用符を付けることを習慣化することくらいでしょうか。しかしいちいち「%~I」と入力するのはちょっと手間ですね・・・
救いはなかった。