You do not need a lot of code:
IFS=$'\n' sorted=($(sort <<<"${array[*]}")) unset IFS
Supports spaces in elements (unless it is a newline) and works in Bash 3.x.
eg.:
$ array=("ac" bf "3 5") $ IFS=$'\n' sorted=($(sort <<<"${array[*]}")); unset IFS $ printf "[%s]\n" "${sorted[@]}" [3 5] [ac] [b] [f]
Note. @sorontar pointed out that caution should be exercised if elements contain wildcards such as * or ? :
The sorted = ($ (...)) part uses the split and glob operator. You must turn off glob: set -f or set -o noglob or shopt -op noglob , or an array element, for example * , will be expanded to a list of files.
What's happening:
The result is six things that happen in the following order:
IFS=$'\n'"${array[*]}"<<<sortsorted=($(...))unset IFS
First, IFS=$'\n'
This is an important part of our operation, which affects results 2 and 5 as follows:
Given:
"${array[*]}" expands to each element bounded by the first IFS charactersorted=() creates elements by dividing each IFS character
IFS=$'\n' sets up the elements to expand using a new line as a separator, and then create them so that each line becomes an element. (i.e. split on a new line.)
Newline separation is important because sort works like this (sorting by line). Separating only with a new line is not so important, but it is necessary to keep elements containing spaces or tabs.
The default IFS is a space, a tab, followed by a new line, and it is not suitable for our work.
The rest of the sort <<<"${array[*]}"
<<< , called here strings , takes the extension "${array[*]}" as described above, and feeds it to standard sort input.
In our sort example, the following line is passed:
ac b f 3 5
Since sort sorts, it produces:
3 5 ac b f
Next, the sorted=($(...))
The $(...) , called command substitution , causes its contents ( sort <<<"${array[*]} ) to be run as a normal command, while the standard output received is output as a literal that goes anywhere $(...) .
In our example, this produces something similar to simple spelling:
sorted=(3 5 ac b f )
sorted then becomes an array, which is created by breaking this literal on each new line.
Finally, unset IFS
This resets the IFS value to its default value, and this is just good practice.
This is done so that we do not create problems with anything that relies on IFS later in our script. (Otherwise, we need to remember that we have all changed - which may be impractical for complex scenarios.)