![バッチファイル。変数内の変数](https://rvso.com/image/1413962/%E3%83%90%E3%83%83%E3%83%81%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%80%82%E5%A4%89%E6%95%B0%E5%86%85%E3%81%AE%E5%A4%89%E6%95%B0.png)
変数内で変数を使用するにはどうすればよいでしょうか? このコード:
set newvar=%var%var2%%
動作しません。では、どうすればいいでしょうか? これがないとプログラムを書くことができません。
答え1
AFHに同意します。CMDにステートメントを「二重に解析」させる必要がありますset
。しかし、一時的なバッチファイル(または必要な変数を見つけるためにすべての変数を調べる)を必要とせずにこれを行うための簡単な方法を見つけました。サブルーチンと遅延変数展開と呼ばれるトリックを使用します。遅延展開を有効にするには、次を追加します。
setlocal enabledelayedexpansion
バッチ ファイルの先頭付近に記述します。遅延変数展開の目的は多少複雑です (詳細については、SET /?
とを参照してください)。ただし、重要な点は、に加えて もSETLOCAL /?
変数を参照できるということです。!variable_name!
%variable_name%
では、始めましょう:
@echo off
setlocal enabledelayedexpansion
set var1=red
set var2=orange
set var3=yellow
set A=2
call :kludge var%A%
echo Newvar is %newvar%.
goto :eof
:kludge
set newvar=!%1!
exit /b
にジャンプすると:kludge
、文はまず に変換されますset newvar=!var2!
( %1
サブルーチンの最初の引数である は であるためvar2
)。その後 が変換されset newvar=orange
ます (文が であった場合と同様set newvar=%var2%
)。したがってnewvar
は に設定されますorange
。
ちなみに、goto :eof
と はexit /b
互換性があります。サブルーチン内 (つまり、ステートメントで到達した場所call
) から呼び出された場合は、呼び出し元に戻ります。それ以外の場合は、バッチ ファイルの末尾へのジャンプのように動作し、親の対話型コマンド プロンプトを消去せずにバッチ ジョブを終了します。
答え2
比較的遅い方法です。CALL コマンドは、変数拡張の追加レベルを提供します。外側の変数名の周りのパーセントは 2 倍になり、内側の変数が拡張されるまで拡張を遅らせます。
@echo off
setlocal
set "var1=value"
set "var2=1"
call set "newvar=%%var%var2%%%"
より優れた方法は、遅延展開を使用することです。これは、まず SETLOCAL ENABLEDELAYEDEXPANSION で有効にする必要があります。パーセント内の変数は、行が解析されるときに展開されます。感嘆符内の変数は、行が実行される直前の解析後に展開されます。
@echo off
setlocal enableDelayedExpansion
set "var1=value"
set "var2=1"
set "newvar=!var%var2%!"
答え3
一般的に、このようなシナリオは避けるようにします。可能ではありますが、パフォーマンスは低く、読みやすさもあまり良くありません。基本的に、コマンドの出力を解析する必要がありますset
。
set index=9
set var9=Goal
echo %var9%
for /F "usebackq tokens=1* delims==" %I in (`set`) do if "%I" == "var%index%" set result=%J
echo %result%