Bash
合併關聯數組 BASH 中的重複鍵
我有一個包含重複項的數組,例如
THE_LIST=( "'item1' 'data1 data2'" "'item1' 'data2 data3'" "'item2' 'data4'" )
基於上述,我想創建一個關聯數組,將其分配
itemN
為鍵和dataN
值。我的程式碼遍歷列表,並像這樣分配 key => 值(附加功能被縮短,因為它在列表上執行一些額外的工作):
function get_items(){ KEY=$1 VALUES=() shift $2 for VALUE in "$@"; do VALUES[${#VALUES[@]}]="$VALUE" done } declare -A THE_LIST for ((LISTID=0; LISTID<${#THE_LIST[@]}; LISTID++)); do eval "LISTED_ITEM=(${THE_LIST[$LISTID]})" get_items "${LISTED_ITEM[@]}" THE_LIST=([$KEY]="${VALUES[@]}") done
當我列印數組時,我得到類似:
item1: data1 data2 item1: data2 data3 item2: data4
但相反,我想得到:
item1: data1 data2 data3 item2: data4
找不到合併重複鍵以及刪除鍵的重複值的方法。
這裡的方法是什麼?
更新
實際程式碼是:
THE_LIST=( "'item1' 'data1 data2'" "'item1' 'data2 data3'" "'item2' 'data4'" ) function get_backup_locations () { B_HOST="$2" B_DIRS=() B_DIR=() shift 2 for B_ITEM in "$@"; do case "$B_ITEM" in -*) B_FLAGS[${#B_FLAGS[@]}]="$B_ITEM" ;; *) B_DIRS[${#B_DIRS[@]}]="$B_ITEM" ;; esac done for ((B_IDX=0; B_IDX<${#B_DIRS[@]}; B_IDX++)); do B_DIR=${B_DIRS[$B_IDX]} ...do stuff here... done } function get_items () { for ((LOCIDY=0; LOCIDY<${#LOCATIONS[@]}; LOCIDY++)); do eval "LOCATION=(${LOCATIONS[$LOCIDY]})" get_backup_locations "${LOCATION[@]}" THE_LIST=([$B_HOST]="${B_DIR[@]}") done | sort | uniq }
列印數組時:
for i in "${!THE_LIST[@]}"; do echo "$i : ${THE_LIST[$i]}" done
我明白了
item1: data1 data2 item1: data2 data3 item2: data4
如果保證鍵和值是純字母數字的,那麼這樣的事情可能會起作用:
declare -A output make_list() { local IFS=" " declare -A keys # variables declared in a function are local by default for i in "${THE_LIST[@]}" do i=${i//\'/} # since everything is alphanumeric, the quotes are useless declare -a keyvals=($i) # split the entry, filename expansion isn't a problem key="${keyvals[0]}" # get the first value as the key keys["$key"]=1 # and save it in keys for val in "${keyvals[@]:1}" do # for each value declare -A "$key[$val]=1" # use it as the index to an array. done # Duplicates just get reset. done for key in "${!keys[@]}" do # for each key declare -n arr="$key" # get the corresponding array output["$key"]="${!arr[*]}" # and the keys from that array, deduplicated done } make_list declare -p output # print the output to check
通過範例輸入,我得到以下輸出:
declare -A output=([item1]="data3 data2 data1" [item2]="data4" )
數據項無序,但已刪除重複數據。
最好將 Python 與
csv
模組一起使用。