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
これを実現するためにスクリプトを変更するにはどうすればよいですか?
コメント
回答
これは配列キーのリストを使用して行うことができます。 bash
のマニュアルページから:
${!name[@]}
${!name[*]}
配列キーのリスト。 nameが配列変数の場合、nameで割り当てられた配列インデックス(キー)のリストに展開されます。 nameが配列でない場合、nameが設定されている場合は
0
に展開され、それ以外の場合は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
コメント
- この回答は目的の結果を達成しますが、printfステートメントによって不必要に難読化されています。例:
printf "$i=(${AR[i]})\n"
またはecho "$i=(${ARi]})"
はどちらも、キーの取得方法を示すことで少し余分になります& varですが、厳密に言えばecho "$i"
がOPに回答します。残りは" bash fu " 🙂 - それが不可能な理由:
a=(1 2);echo ${a[0]} # result: 1
?
回答
jordanmの回答に加えて、C
bash
のループのように:
for ((idx=0; idx<${#array[@]}; ++idx)); do echo "$idx" "${array[idx]}" done
コメント
- スパース配列でない場合のみ…
回答
次のようなことができます:
#!/bin/bash AR=("foo" "bar" "baz" "bat") length=${#AR[@]} for (( i = 0; i < length; i++ )); do echo "$i" done
出力:
0 1 2 3
コメント
- これは pfnueselの答えはまだ言っていませんか?
- 私は間違っているかもしれませんが、pfnueselsの答えは各反復で配列の長さを再評価しませんか?
"${array[@]}"
の代わりに"${array[*]}"
が必要です。@
の代わりに*
を使用すると、多かれ少なかれ配列ではなく文字列として扱われます。