Bash

如何在中間的某個索引處移動 bash 數組?

  • May 6, 2021
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.

為什麼在第 13 行,標準輸出是空白的,考慮到從第 12 行的標準輸出判斷,數組似乎已經更新?

因此,我應該怎麼做才能得到預期的答案“69”?

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")

數組a沒有元素 2 到 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

一步刪除元素和重新編號數組的替代方法

再次,讓我們定義numbers

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

正如Toby Speight在評論中所建議的,一種刪除第四個元素並在一個步驟中重新編號剩餘元素的方法:

$ 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")

如您所見,第四個元素被刪除,所有剩餘的元素都被重新編號。

${numbers[@]:0:4}slices 數組numbers:它採用從元素 0 開始的前四個元素。

同樣,${numbers[@]:5}slice array 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 name, wherename是一個數組, or unset name[subscript], where subscriptis * or @, 刪除整個數組。

引用自:https://unix.stackexchange.com/questions/393069