问题
How do I sort an associative array in bash?
For example, I have array in bash:
[0,0]="Max"
[0,1]="25"
[1,0]="Vladimir"
[1,1]="0"
[2,0]="Mayki"
[2,1]="50"
Output must be:
- Mayki - 50
- Max - 25
- Vladimir - 0
I don't know how sort this array.
Additional Info: I parse assoc array from text file ("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"
回答1:
There are a couple of approaches to this problem. One of the easiest is probably to read the pairs of strings into an indexed array and then reverse numeric sort on the number field:
#!/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
Output
$ bash sort_assoc.sh
Mayki - 50
Max - 25
Vladimir - 0
回答2:
I'd probably switch to Perl for such a complicated task, even if it's still doable in 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
It would be much simpler if you defined the array like
arr=([Max]=25
[Vladimir]=0
[Mayki]=50
[Ivan]=10
)
for paren in "${!arr[@]}" ; do
echo $paren ${arr[$paren]}
done | sort -rnk2
来源:https://stackoverflow.com/questions/29850406/how-a-sort-associative-array-bash-script