如何排序关联数组 bash 脚本



如何在 bash 中对关联数组进行排序?

例如,我在 bash 中有数组:

[0,0]="Max"
[0,1]="25"
[1,0]="Vladimir"
[1,1]="0"
[2,0]="Mayki"
[2,1]="50"

输出必须为:

  1. 迈基 - 50
  2. 最大 - 25
  3. 弗拉基米尔 - 0

我不知道如何对这个数组进行排序。

附加信息:我从文本文件("log.txt")解析assoc数组

    #!/bin/bash
declare -A b_array
# Read the file in parameter and fill the array named "array"
getArray() {
    i=0
    w=9
    count=10
    while read line # Read a line
    do
        k=0
        #array[i]=$line # Put it into the array
        #b_array[$i,0]=$(grep -Eo "(http|https)://[a-zA-Z0-9./?=_-]*" <<<"$line") 
        for word in $line;
          do  
                  #echo $k;
                  #echo $word;
                  if [ "$k" = "$w" ]; then
                      if [ $word != "-" ]; then
                        b_array[$i]=$word 
                        i=$(($i + 1))
                      fi 
                  fi 
                  k=$(($k + 1))
            done

    done < $1
}
getArray "log.txt"

有几种方法可以解决这个问题。最简单的方法之一可能是将字符串对读取到索引数组中,然后在数字字段上反向数字排序:

#!/bin/bash
declare -A arr
declare -a sa
arr[0,0]="Max"
arr[0,1]="25"
arr[1,0]="Vladimir"
arr[1,1]="0"
arr[2,0]="Mayki"
arr[2,1]="50"
## convert associative array to 
#  indexed array of string pairs
#  (e.g. "Max - 25", "Mayki - 50" )
for i in ${!arr[@]}; do                         # for each key in ar
    x=${i%,*}                                   # separate x,y values
    y=${i#*,}
    (( y == 1 )) && continue                    # if y == 1, continue
    for j in ${!arr[@]}; do                     # for each key in ar
        _x=${j%,*}                              # separate _x,_y values
        _y=${j#*,}
        ((x != _x)) || ((_y == 0)) && continue  # if x != _x, or _y == 0, continue
        sa+=( "${arr[$i]} - ${arr[$j]}" )       # add combined string to indexed sa
    done
done
sort -r -k3 -n <<<"$(printf "%sn" "${sa[@]}")" # numeric reverse sort sa on key3
exit 0

输出

$ bash sort_assoc.sh
Mayki - 50
Max - 25
Vladimir - 0

我可能会切换到Perl来完成如此复杂的任务,即使它在bash中仍然可以做到:

#!/bin/bash
declare -A arr
arr=([0,0]="Max"
     [0,1]="25"
     [1,0]="Vladimir"
     [1,1]="0"
     [2,0]="Mayki"
     [2,1]="50"
     [10,0]=Ivan
     [10,1]=10
    )
indices=( $( (IFS=$'n' ; echo "${!arr[*]}") | grep ,0 | cut -d, -f1 | sort ) )
for i in "${indices[@]}" ; do
    echo ${arr[$i,0]} ${arr[$i,1]}
done | sort -rnk2

如果您定义数组,例如

arr=([Max]=25
     [Vladimir]=0
     [Mayki]=50
     [Ivan]=10
    )
for paren in "${!arr[@]}" ; do
    echo $paren ${arr[$paren]}
done | sort -rnk2

最新更新