3

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!

9
  • 7
    Try sort -r to reverse order. Commented Oct 22, 2016 at 14:23
  • it works! thanks a lot! Commented Oct 22, 2016 at 14:32
  • 2
    You can also write arr=($(printf '%s\n' "${nameArr[@]}" | sort -r)) Commented Oct 22, 2016 at 14:38
  • i would say it does not matter because the complexity should be the same. Am I right? Commented Oct 22, 2016 at 15:10
  • the printf '%s\n' ${arr[@]} is just a good reminder that it will process all values one-by-one from the input string, replacing a for loop for (in this case), the same functionality. (Think how easy extending this to process 2 words at a time with printf would be). You can also go for the idea that the shortest code wins ;-) . Good luck. Commented Oct 22, 2016 at 15:50

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.