Bash Associative Array Sorting By Value
Answer :
You can easily sort your output, in descending numerical order of the 3rd field:
for k in "${!authors[@]}" do echo $k ' - ' ${authors["$k"]} done | sort -rn -k3
See sort(1) for more about the sort
command. This just sorts output lines; I don't know of any way to sort an array directly in bash.
I also can't see how the above can give you names ("Pushkin" et al.) as array keys. In bash, array keys are always integers.
Alternatively you can sort the indexes and use the sorted list of indexes to loop through the array:
authors_indexes=( ${!authors[@]} ) IFS=$'\n' authors_sorted=( $(echo -e "${authors_indexes[@]/%/\n}" | sed -r -e 's/^ *//' -e '/^$/d' | sort) ) for k in "${authors_sorted[@]}"; do echo $k ' - ' ${authors["$k"]} done
Extending the answer from @AndrewSchulman, using -rn as a global sort option reverses all columns. In this example, authors with the same associative array value will be output by reverse order of name.
For example
declare -A authors authors=( [Pushkin]=10050 [Gogol]=23 [Dostoyevsky]=9999 [Tolstoy]=23 ) for k in "${!authors[@]}" do echo $k ' - ' ${authors["$k"]} done | sort -rn -k3
will output
Pushkin - 10050 Dostoyevsky - 9999 Tolstoy - 23 Gogol - 23Options for sorting specific columns can be provided after the column specifier. i.e.
sort -k3rn
Note that keys can be specified as spans. Here -k3
happens to be fine because it is the final span, but to use only column 3 explicitly (in case further columns were added), it should be specified as -k3,3
, Similarly to sort by column three in descending order, and then column one in ascending order (which is probably what is desired in this example):
declare -A authors authors=( [Pushkin]=10050 [Gogol]=23 [Dostoyevsky]=9999 [Tolstoy]=23 ) for k in "${!authors[@]}" do echo $k ' - ' ${authors["$k"]} done | sort -k3,3rn -k1,1
will output
Pushkin - 10050 Dostoyevsky - 9999 Gogol - 23 Tolstoy - 23
Comments
Post a Comment