如何排序关联数组bash脚本

时间:2015-04-24 14:40:24

标签: bash sorting associative

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

例如,我在bash中有数组:

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

输出必须是:

  1. Mayki - 50
  2. Max - 25
  3. 弗拉基米尔 - 0
  4. 我不知道这个数组是如何排序的。

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

        #!/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"
    

2 个答案:

答案 0 :(得分:1)

这个问题有几种方法。其中一个最简单的方法是将字符串对读入索引数组,然后对数字字段进行反向数字排序:

#!/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 "%s\n" "${sa[@]}")" # numeric reverse sort sa on key3

exit 0

<强>输出

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

答案 1 :(得分: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