中間の一部のインデックスでbash配列を移動する方法は?

中間の一部のインデックスでbash配列を移動する方法は?
1  #!/bin/bash
2  # query2.sh
3
4  numbers=(53 8 12 9 784 69 8 7 1)
5  i=4
6
7  echo ${numbers[@]} # <--- this echoes "53 8 12 9 784 69 8 7 1" to stdout.
8  echo ${numbers[i]} # <--- this echoes "784" to stdout.
9
10 unset numbers[i]
11
12 echo ${numbers[@]} # <--- this echoes "53 8 12 9 69 8 7 1" to stdout.
13 echo ${numbers[i]} # <--- stdout is blank.

配列が12行のstdoutに基づいて更新されたように見えますが、13行のstdoutが空であるのはなぜですか?

では、予想される答え「69」を得るにはどうすればよいですか?

ベストアンサー1

unset要素を削除します。残りの要素の番号を再度付けません。

私たちはこれを使ってdeclare -p何が起こっているのかを確認できますnumbers

$ unset "numbers[i]"
$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [5]="69" [6]="8" [7]="7" [8]="1")

観察にはnumbersもう要素がありません4

他の例

観察する:

$ a=()
$ a[1]="element 1"
$ a[22]="element 22"
$ declare -p a
declare -a a=([1]="element 1" [22]="element 22")

配列にはa2から21までの要素はありません。 Bashでは、配列インデックスが連続的である必要はありません。

インデックス番号の再割り当てに推奨される方法

numbers欠けている要素を持つ配列から始めましょう4

$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [5]="69" [6]="8" [7]="7" [8]="1")

インデックスを変更するには:

$ numbers=("${numbers[@]}")
$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [4]="69" [5]="8" [6]="7" [7]="1")

これで要素番号があり、4値があります69

1つのステップで要素を削除して配列番号を再割り当てする別の方法

再定義してみましょうnumbers

$ numbers=(53 8 12 9 784 69 8 7 1)

提案通りトビースペートコメントには、5番目の要素(インデックス4)を削除し、1つのステップで残りの要素の番号を再割り当てする方法があります。

$ numbers=("${numbers[@]:0:4}" "${numbers[@]:5}")
$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [4]="69" [5]="8" [6]="7" [7]="1")

ご覧のとおり、5番目の要素が削除され、残りのすべての要素の番号が再割り当てされます。

${numbers[@]:0:4}Slices array numbers:要素0から始めて、最初の4つの要素を取得します。

同様に${numbers[@]:5}、配列を分割すると、numbers要素5から配列の終わりまですべての要素が取得されます。

配列のインデックスを取得する

これ価値${a[@]}見つけるために配列を取得するために使用できます。索引(または)この値に対応するを使用してください${!a[@]}

たとえば、配列にnumbers要素が欠落していると考えてみましょう4

$ declare -p numbers
declare -a numbers=([0]="53" [1]="8" [2]="12" [3]="9" [5]="69" [6]="8" [7]="7" [8]="1")

どのインデックスが割り当てられているかを確認するには、次の手順に従ってください。

$ echo "${!numbers[@]}"
0 1 2 3 5 6 7 8

今回も4インデックスリストにその値がありません。

文書

からman bash

組み込みunset関数は配列を破壊するために使用されます。 unset name[subscript]indexから配列要素を削除しますsubscript。インデックス配列の負の添え字は、上記のように説明されます。パス名拡張による不要な副作用を防ぐために注意を払う必要があります。 unset namename配列はどこにありますか、unset name[subscript]どこにsubscriptありますか? * または @、配列全体を削除します。

おすすめ記事