web-dev-qa-db-ja.com

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

Bashシェルスクリプトで配列をループしているときに配列インデックス変数にアクセスしたいのですが。

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

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

foo
bar
baz
bat

私が求める結果は:

0
1
2
3

これを達成するためにスクリプトをどのように変更しますか?

21
Mowzer

これを行うには、配列キーのリストを使用します。 bash manページから:

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

配列キーのリスト。 nameが配列変数の場合、nameに割り当てられた配列インデックス(キー)のリストに展開されます。 nameが配列でない場合、nameが設定されている場合は0に展開され、それ以外の場合はnullに展開されます。 @が使用され、展開が二重引用符で囲まれている場合、各キーは個別のWordに展開されます。

あなたの例のために:

#!/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
27
jordanm

ヨルダンの回答に加えて、Cbashのようなループを実行することもできます。

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

あなたはこのようなことをすることができます:

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

出力:

0
1
2
3
1
F.9876