`zsh` で動的に名前が付けられた変数を増やす方法

`zsh` で動的に名前が付けられた変数を増やす方法

次のように、 で動的に名前が付けられた変数を作成するとしますzsh

name="hello"
typeset $name=42
echo ${(P)${name}} # Prints the variable $hello, which is 42

さて、上記の変数を増分または変更したいが、その直接の名前がわからない場合、次のようなものが機能すると予想されます。

(( ${(P)${name}} = ${(P)${name}} + 1 )) # Set $hello to 43?

上記は機能しません。何が機能するのでしょうか?

答え1

$ name=hello
$ hello=42
$ (($name++))
$ echo $hello
43

Korn のようなシェルと同じです。または POSIX の場合:

$ name=hello
$ hello=42
$ : "$(($name += 1))"
$ echo "$hello"
43

重要なのは、すべてのパラメータ展開、コマンド置換、および算術展開が、算術式が評価される前に算術式内で実行されることです。

((something))

と類似しています

let "something"

したがって、(($name++))( のようにlet "$name++") では、まず が に展開されhello++、それが変数++に適用された演算子として評価されますhello

POSIXには演算子shはないが、算術演算子((...))はある。$((...))拡大演算子。 はありませんが++(ただし、実装では、単項演算子や二項演算子の組み合わせを要求する代わりに、拡張として 1 つを含めることができます+)、 はあります+=

: "$((...))"whereが null コマンドである場合、を使用すると:、ksh の に似たものが得られます((...))。 厳密に同等のものは ですが[ "$((...))" -ne 0 ]((expression))式が 0 に解決されると は false を返します。

答え2

次のようにすれば解決するようです:

 typeset $name=$(( ${(P)${name}} + 1 ))

代替の方法があれば、ぜひ教えてください。

関連情報