Cómo incrementar una variable con nombre dinámico en `zsh`

Cómo incrementar una variable con nombre dinámico en `zsh`

Digamos que uno crea una variable con nombre dinámico en zsh, así:

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

Ahora, supongamos que uno quiere incrementar o cambiar dicha variable, pero sin saber su nombre directo, es decir, esperaría que funcione algo similar a lo siguiente:

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

Lo anterior no funciona, ¿qué funcionará?

Respuesta1

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

Como en cualquier caparazón tipo Korn. O POSIXly:

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

El punto es que todas las expansiones de parámetros, sustituciones de comandos y expansiones aritméticas se realizan dentro de expresiones aritméticas antes de que se evalúe la expresión aritmética.

((something))

es parecido a

let "something"

Entonces, en (($name++))(como let "$name++"), primero se expande hello++y se evalúa como el ++operador aplicado a la hellovariable.

POSIX shno tiene ((...))operador pero tiene la $((...))aritméticaexpansiónoperador. No es así ++(aunque permite que las implementaciones tengan uno como extensión en lugar de requerir que sea una combinación de +operadores unarios y/o binarios), pero lo tiene +=.

Al usar : "$((...))"el :comando null, obtenemos algo similar a ksh ((...)). Aunque un equivalente estricto sería [ "$((...))" -ne 0 ], as ((expression))devuelve falso cuando la expresión se resuelve en 0.

Respuesta2

Parece que esto lo hará:

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

Cualquier método alternativo será muy apreciado.

información relacionada