preneond
preneond

Reputation: 531

How to sort string array in descending order in Bash?

let's say I have an array:

nameArr=("Leia", "Darth Vader", "Anakin", "Han Solo", "Yoda")

and I would like to sort in descending order. How could I do it in Bash shell scripting? In ascending order I am using command:

arrAsc=($(for l in ${nameArr[@]}; do echo $l; done | sort))

Thanks a lot for help!

Upvotes: 3

Views: 12527

Answers (2)

David C. Rankin
David C. Rankin

Reputation: 84551

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/bash

nameArr=("Leia", "Darth Vader", "Anakin", "Han Solo", "Yoda")

IFS=$'\n'           ## only word-split on '\n'
nameArr=( $(printf "%s\n" ${nameArr[@]} | sort -r ) )  ## reverse sort

declare -p nameArr  ## simply output the array

Example Use/Output

Calling the script results in the following:

$ bash revarr.sh
declare -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.

Upvotes: 2

Jeffrey Cash
Jeffrey Cash

Reputation: 1073

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

Upvotes: 1

Related Questions