Come eseguire l'iterazione sugli indici dell'array in zsh?
In bash possiamo iterare sull'indice di un array come questo
~$ for i in "${!test[@]}"; do echo $i; done
dove test è un array, diciamo,
~$ test=(a "b c d" e f)
in modo che l'output assomigli
0
1
2
3
Tuttavia, quando faccio lo stesso in zsh ottengo un errore:
➜ ~ for i in "${!test[@]}"; do echo $i; done
zsh: event not found: test[@]
Cosa sta succedendo?
Qual è il modo corretto di iterare sugli indici in zsh?
Risposte
zshgli array sono array normali come nella maggior parte delle altre shell e linguaggi, non sono come negli array associativi ksh/bash con chiavi limitate a numeri interi positivi (ovvero array sparsi). zshha un tipo di variabile separato per gli array associativi (con le chiavi che sono sequenze arbitrarie di 0 o più byte).
Quindi gli indici per gli array normali sono sempre numeri interi da 1 alla dimensione dell'array (supponendo che la compatibilità ksh non sia abilitata, nel qual caso gli indici dell'array iniziano da 0 invece che da 1).
Così:
typeset -a array
array=(a 'b c' '')
for ((i = 1; i < $#array; i++)) print -r -- $array[i]
Sebbene in genere, eseguirai il ciclo sui membri dell'array, non sul loro indice:
for i ("$array[@]") print -r -- $i
(la "$array[@]"sintassi, al contrario di $array, conserva gli elementi vuoti).
O:
print -rC1 -- "$array[@]"
per passare tutti gli elementi a un comando.
Ora, per scorrere le chiavi di un array associativo , la sintassi è:
typeset -A hash
hash=(
key1 value1
key2 value2
'' empty
empty ''
)
for key ("${(@k)hash}") printf 'key=%s value=%s\n' "$key" "$hash[$key]"
(con di nuovo @dentro le virgolette utilizzate per preservare gli elementi vuoti).
Sebbene tu possa anche passare chiavi e valori ai comandi con:
printf 'key=%s value=%s\n' "${(@kv)hash}"
Per ulteriori informazioni sulle varie progettazioni di array nelle shell simili a Bourne, vedere Test per il supporto di array tramite shell
Come detto in questo articolo Guida per l'utente alla Z-Shell - Capitolo 5: Sostituzioni :
Questo viene esteso per altri parametri nel modo seguente:
% array=(one two three)
% print -l "${array[@]}"
one
two
three
e più in generale per tutte le forme di sostituzione utilizzando un altro flag, (@):
% print -l "${(@)array}"
one
two
three
Quindi, forse prova solo a usare il secondo modo?