Como incrementar uma variável nomeada dinamicamente em `zsh`

Como incrementar uma variável nomeada dinamicamente em `zsh`

Digamos que alguém crie uma variável nomeada dinamicamente em zsh, assim:

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

Agora, suponha que alguém queira incrementar ou alterar a referida variável, mas sem saber seu nome direto, ou seja, eu esperaria que algo semelhante ao seguinte funcionasse:

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

O que foi dito acima não funciona - o que funcionará?

Responder1

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

Assim como em qualquer shell do tipo Korn. Ou POSIXly:

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

A questão é que todas as expansões de parâmetros, substituições de comandos e expansões aritméticas são feitas dentro de expressões aritméticas antes da expressão aritmética ser avaliada.

((something))

é similar a

let "something"

Então, em (($name++))(como let "$name++"), isso é primeiro expandido para hello++e avaliado como o ++operador aplicado à hellovariável.

POSIX shnão tem ((...))operador, mas tem $((...))aritméticaexpansãooperador. Ele não possui ++(embora permita que as implementações tenham um como extensão em vez de exigir que seja uma combinação de +operadores unários e/ou binários), mas possui +=.

Usando : "$((...))"where :is o comando null, obtemos algo semelhante ao ksh's ((...)). Embora um equivalente estrito fosse [ "$((...))" -ne 0 ], as ((expression))retorna falso quando a expressão é resolvida como 0.

Responder2

Parece que isso vai resolver:

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

Quaisquer métodos alternativos serão muito apreciados.

informação relacionada