How to sort string array in descending order in Bash? How to sort string array in descending order in Bash? shell shell

How to sort string array in descending order in Bash?


You can do so fairly easily making use of IFS (internal field separator), sort -r, and a little help from printf. Using command substitution you can output and sort the array and then simply read the sorted results back into nameArr. For instance:

#!/bin/bashnameArr=("Leia", "Darth Vader", "Anakin", "Han Solo", "Yoda")IFS=$'\n'           ## only word-split on '\n'nameArr=( $(printf "%s\n" ${nameArr[@]} | sort -r ) )  ## reverse sortdeclare -p nameArr  ## simply output the array

Example Use/Output

Calling the script results in the following:

$ bash revarr.shdeclare -a nameArr='([0]="Yoda" [1]="Leia," [2]="Han Solo," [3]="Darth Vader," [4]="Anakin,")'

note: don't forget to restore the default IFS=$' \t\n' (space, tab, newline) when done with the sort if your script continues.


Your question inspired me to whip up a function that I'm sure will come in handy in the future:

sort_array () { local v="$1[*]" IFS=$'\n'; read -d $'\0' -a "$1" < <(sort "${@:2}" <<< "${!v}"); }

Usage: sort_array NameOfArrayVariable [flags to pass to sort command]

With nameArr=("Leia", "Darth Vader", "Anakin", "Han Solo", "Yoda"):
calling sort_array nameArr will result in nameArr containing ("Anakin," "Darth Vader," "Han Solo," "Leia," "Yoda"); calling sort_array nameArr -r will result in nameArr containing ("Yoda" "Leia," "Han Solo," "Darth Vader," "Anakin,")

Also, just a heads up, when you declare or set an array in bash, you do not comma separate elements, as "Leia", is the same as "Leia," unless you set IFS to contain a comma.

This function also works well with integer arrays:

$ nums=()$ for ((i=0; i<10; ++i)); do nums+=($RANDOM); done$ echo "${nums[@]}";22928 7011 18865 24027 18559 9037 3885 10873 32369 21932$ sort_array nums -n$ echo "${nums[@]}"3885 7011 9037 10873 18559 18865 21932 22928 24027 32369$ sort_array nums -nr $ echo "${nums[@]}"32369 24027 22928 21932 18865 18559 10873 9037 7011 3885