同時在 2 個數組的相同索引中回顯值
我有 2 個數組要同時在 bash 腳本中處理。第一個數組包含某種標籤。第二個數組包含值,如下所示
LABELS=(label1 label2 label3 labe4 ) VALUES=(91 18 7 4)
需要的是:一個循環,它將回顯 LABELS 數組 & 中的索引項,並在 VALUES 數組中該項的相應值前面,如下所示
label1 91 label2 18 label3 7 label4 4
我猜嵌套循環不起作用,我在下面嘗試過,但它不會按語法工作
for label in {LABELS[@]} && value in {VALUES[@]} do echo ${label} ${value} done
只需使用數字索引並通過索引引用數組元素:
labels=(label1 label2 label3 label4) values=(91 18 7 4) for((i=0; i<"${#labels[@]}"; i++ )); do printf '%s: %s\n' "${labels[i]}" "${values[i]}" done
或者,如果您使用的是相對較新的(>= 版本 4)bash 或其他支持關聯數組的 shell,只需使用單個數組即可:
declare -A values=( ["label1"]=91 ["label2"]=18 \ ["label3"]=7 ["label4"]=4 ) for label in "${!values[@]}"; do printf '%s: %s\n' "$label" "${values[$label]}" done
我將變數名稱更改為小寫,因為在 shell 腳本中對局部變數使用大寫字母是不好的做法,因為全域環境變數按約定大寫,因此在腳本中使用大寫字母可能會導致變數名稱衝突。
由於您的兩個數組具有完全相同的索引(0、1、2 和 3),因此您可以使用
${!array[@]}
迭代其中一個數組的索引(AKA 鍵)並使用該迭代器訪問兩個數組中的值。這適用於“索引數組”(即整數索引)和“關聯數組”(字元串索引)。
例如
LABELS=(label1 label2 label3 labe4 ) VALUES=(91 18 7 4) for i in "${!LABELS[@]}"; do echo "${LABELS[i]}" "${VALUES[i]}" done
輸出:
label1 91 label2 18 label3 7 labe4 4
順便說一句,您還可以使用這樣的循環來填充關聯數組,這在您不能同時讀取鍵和值的情況下很有用,就像您的兩個手動定義的數組一樣:
LABELS=(label1 label2 label3 labe4) VALUES=(91 18 7 4) declare -A LV # declare LV to be an associative array for i in "${!LABELS[@]}"; do LV["${LABELS[$i]}"]="${VALUES[$i]}"; done declare -p LV
輸出:
declare -A LV=([labe4]="4" [label3]="7" [label2]="18" [label1]="91" )
從現在開始,您的腳本可以使用關聯數組
$LV
直接訪問鍵中的值,例如$ echo "${LV[label1]}" 91
您還可以使用 C 風格的 for 循環,如 @terdon 和 @NickMatteo 的答案(從 0 循環到數組的長度),但這僅適用於數組索引是數字且連續且數組中沒有間隙(未定義索引)的情況.
在許多/大多數情況下,這很好,因為數組通常是用連續的索引號定義的,但在其他情況下,它不會按預期工作 - 例如,如果為 1、3、5、7、11、13、17
$array
定義了索引然後${#array[@]}
將返回 7 並且這樣的循環將從 0..6 (如果您使用<=
而不是<
作為測試條件,則為 0..7 )而不是數組中的實際索引列表進行迭代。例如:
$ for i in 1 3 5 7 11 13 17 ; do let array[$i]=$i*$i ; done $ declare -p array declare -a array=([1]="1" [3]="9" [5]="25" [7]="49" [11]="121" [13]="169" [17]="289") $ echo "${#array[@]}" 7 $ for ((i=0; i<"${#array[@]}"; i++)); do echo $i: "${array[$i]}" ; done 0: 1: 1 2: 3: 9 4: 5: 25 6: $ echo "${!array[@]}" 1 3 5 7 11 13 17 $ for i in "${!array[@]}"; do echo $i: "${array[$i]}"; done 1: 1 3: 9 5: 25 7: 49 11: 121 13: 169 17: 289