bashシェルスクリプトループから配列インデックス変数にアクセスしますか?


18

bashシェルスクリプトで配列をループしながら、配列インデックス変数にアクセスしたい。

myscript.sh
#!/bin/bash
AR=('foo' 'bar' 'baz' 'bat')
for i in ${AR[*]}; do
  echo $i
done

上記のスクリプトの結果は次のとおりです。

foo
bar
baz
bat

私が求める結果は次のとおりです。

0
1
2
3

これを達成するためにスクリプトを変更するにはどうすればよいですか?


6
また、の"${array[*]}"代わりに基本的には決して必要ないことに注意してください"${array[@]}"。多かれ少なかれの*代わりにを使用すると@、配列ではなく文字列として扱われます。
ヨルダン

回答:


23

これは、配列キーのリストを使用して実行できますbashmanページから:

${!name[@]}
${!name[*]}

配列キーのリスト。nameが配列変数の場合、nameに割り当てられた配列インデックス(キー)のリストに展開します。nameが配列ではない0場合、nameが設定されている場合は展開され、そうでない場合はnullになります。ときは、@使用および拡張は別々の単語に二重引用符、各キーは膨張内に表示されています。

あなたの例:

#!/bin/bash
AR=('foo' 'bar' 'baz' 'bat')
for i in "${!AR[@]}"; do
  printf '${AR[%s]}=%s\n' "$i" "${AR[i]}"
done

この結果:

${AR[0]}=foo
${AR[1]}=bar
${AR[2]}=baz
${AR[3]}=bat

これは、連続しないインデックスでも機能することに注意してください。

#!/bin/bash
AR=([3]='foo' [5]='bar' [25]='baz' [7]='bat')
for i in "${!AR[@]}"; do
  printf '${AR[%s]}=%s\n' "$i" "${AR[i]}"
done

この結果:

${AR[3]}=foo
${AR[5]}=bar
${AR[7]}=bat
${AR[25]}=baz

1
この答えは望ましい結果を達成しますが、printfステートメントによって不必要に難読化されます。たとえば、キーprintf "$i=(${AR[i]})\n"またはecho "$i=(${ARi]})"変数を取得する方法を示すことで、どちらも少し余分になりますが、厳密に言えばecho "$i"OPに答えます。残りは「bash fu」です:)
dimmech

6

jordanmの答えに加えて、次のCようなlikeループを実行することもできますbash

for ((idx=0; idx<${#array[@]}; ++idx)); do
    echo "$idx" "${array[idx]}"
done

1

次のようなことができます:

#!/bin/bash
AR=('foo' 'bar' 'baz' 'bat')
length=${#AR[@]}
for (( i = 0; i < length; i++ )); do
  echo "$i"
done

出力:

0
1
2
3

1
これは、pfnueselの答え   がまだ言っていないことを何と言って  いますか?
G-Manが「Reinstate Monica」と言う

私は間違っているかもしれませんが、pfnueselsは各反復で配列の長さを再評価しないと答えますか?
クリス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.