whileループで変数を動的に使用する方法

whileループで変数を動的に使用する方法

Unix で次のコマンドを実行するとエラーが発生します。 kshシェルで3行が機能したいです。

while [ ${i} -le 3 ]
do
     var${i}="hello${i}"
     echo "${var}${i}"
     i=`expr ${i} + 1`
done

以下のように出力を取得したいと思います。

hello1
hello2

答え1

POSIXでは、動的名前の変数を使用する必要shがあります。eval

i=0
while [ "$i" -le 3 ]
do
   eval '
     var'"$i"'="hello${i}"
     echo "var$i = ${var'"$i"'}"
   '
   i=$((i+1))
done
echo "${var1}"

を使用するときにeval拡張する必要がある変数のみに渡された引数で拡張されていることを確認することが重要ですeval(そしてその値が削除されたかどうか(ここでは安全な10進数のシーケンスであることがわかります))。

$i上記では、そのうちの2つだけが拡張されました。これを行うには、単一の(強い)引用符を削除し、$i内部二重引用符を挿入しますeval '...'"$i"'...'

正確に引用することは困難であり(正しく引用しないと危険です)、evalできるだけ使用を制限するのが最善です。理想的には、動的変数の内容のみを静的変数として転送するか、その逆に転送することをお勧めします。たとえば、次のようになります。

i=0
while [ "$i" -le 3 ]
do
   var=hello$i # $var with static name
   eval "var$i=\$var" # transfer into variable with dynamic name

   echo "var$i = $var" # use var with static name instead of dynamic one
                       # everywhere else (for which we don't need eval)

   i=$((i+1))
done
echo "${var2}"

///の代わりに配列(または、または最新バージョンの連想配列kshzshを使用bashできます。配列インデックスは/で始まり、配列は希薄です(正の整数に制限されたキーを持つ連想配列に似ています)。一方、他のすべてのシェル(Bourneなどのフロントエンドを含む)では、インデックスは1から始まり、配列は通常です。ソート。yashksh93zshbashkshbash0zshyash

存在するksh/ bash/ zsh -o ksharrays

unset -v var
i=0; while [ "$i" -le 3 ]; do
  var[i]=hello$i
  echo "var[$i]=${var[i]}"
  i=$((i+1))
done
echo "${var[1]}"

または//一般的なPOSIX構文の((...))別の拡張を使用してください。shkshzshbash

unset -v var
i=0; while ((i <= 3)); do
  var[i]=hello$i
  echo "var[$i]=${var[i]}"
  ((++i))
done
echo "${var[2]}"

ksh93または、、bash使用zsh -o ksharrays

unset -v var
for ((i = 0; i <= 3; i++)); do
  var[i]=hello$i
  echo "var[$i]=${var[i]}"
done
echo "${var[3]}"

答え2

ループを使用する方がはるかに簡単ですfor

for i in 1 2 3; do
  echo var$i\ =\ hello$i
done

でテストされましたbash

関連情報