zshで配列インデックスを繰り返す方法は?

zshで配列インデックスを繰り返す方法は?

Bashでは、次のように配列のインデックスを繰り返すことができます。

~$ for i in "${!test[@]}"; do echo $i; done

ここでtestは配列です。例えば

~$ test=(a "b c d" e f)

だから出力は次のようになります

0
1
2
3

しかし、zshで同じことをするとエラーが発生します。

➜ ~ for i in "${!test[@]}"; do echo $i; done
zsh: event not found: test[@]

どうしたの?

zshでインデックスを繰り返す正しい方法は何ですか?

答え1

zsh配列は、他のほとんどのシェルや言語の配列などの一般的な配列であり、キーが正の整数(希少配列とも呼ばれる)に制限されるという点で、ksh / bashの連想配列とは異なります。zsh連想配列には別の変数型があります(キーは0バイト以上のランダムシーケンスです)。

したがって、通常の配列のインデックスは常に1から配列サイズまでの整数です(ksh互換性が有効になっていない場合、配列インデックスは1ではなく0から始まります)。

だから:

typeset -a array
array=(a 'b c' '')
for ((i = 1; i <= $#array; i++)) print -r -- $array[i]

ただし、通常はインデックスではなく配列メンバを繰り返します。

for i ("$array[@]") print -r -- $i

(この"$array[@]"構文は逆$arrayであり、空の要素を保持します。)

または:

print -rC1 -- "$array[@]"

すべての要素をコマンドに渡します。

ここでループを繰り返します。連想配列、構文は次のとおりです。

typeset -A hash
hash=(
  key1  value1
  key2  value2
  ''    empty
  empty ''
)
for key ("${(@k)hash}") printf 'key=%s value=%s\n' "$key" "$hash[$key]"

@空の要素を保存するには、内部引用符を再利用してください)。

以下を使用して、キーと値をコマンドに渡すこともできます。

printf 'key=%s value=%s\n' "${(@kv)hash}"

Bourne型シェルのさまざまな配列設計の詳細については、以下を参照してください。アレイのテストシェルのサポート

答え2

この記事で言うようにZ-Shellユーザーガイド - 第5章:交換:

これは次のように他のパラメータに拡張できます。

% array=(one two three)
% print -l "${array[@]}"
one
two
three

より一般的には、他のフラグ(@)を使用するすべての形式の置換については次のようになります。

% print -l "${(@)array}"
one
two
three

それでは、2番目のアプローチを試してみましょうか?

答え3

中かっこを使用すると、次のようになります{ }

% test=(a "b c d" e f)                 
% for i in {1..$#test}; do echo $i; done
1
2
3
4
%

関連情報