Reputation: 14108
Suppose that I have an array of such data:
arr[0] = "someText1 (x,y,z) a"
arr[1] = "someText2 (x,y,z) b"
How can I sort this array lexicographically [only taking the text into account] using Bash?
Upvotes: 2
Views: 638
Reputation: 189377
Join on newline, pass to sort
.
(IFS=$'\n'; sort <<<"${arr[*]}")
sort <<<"fnord"
simply sends the string "fnord"
as the standard input to sort
; this is a Bash convenience notation for the clumsier echo "fnord" | sort
(plus it avoids the extra process) and similarly, sort <<<"${arr[*]}"
feeds the array to sort
.
Because array pasting depends on the value of IFS
, we change it to a newline so that "${arr[*]}"
will result in a newline-separated list (the default IFS
would cause the entries in the array to be expanded to a space-separated list). In order to not change IFS
permanently, we do this in a subshell; hence, the enclosing parentheses.
The Bash manual page is rather dense, but it's all there; or see the Reference Manual.
Upvotes: 6
Reputation: 75478
This code is in modules but you could just include the needed functions from the other file array.sh to make it complete:
https://github.com/konsolebox/bash-library/blob/master/array/sort.sh
The function is customizable like producing elements or indices, and specializing on strings or integers. Just try to use it.
And one thing, it doesn't depend on external binaries like sort, and doesn't cause possible reinterpretation of data.
Upvotes: 0
Reputation: 183290
One way is to implement your own sorting algorithm; bubble-sort is pretty simple.
Another way is to use an external program, such as sort
, to do your sorting. Here is a shell function that takes the array elements as arguments, and saves a sorted copy of the array into a variable named $SORTED
:
function sort_array () {
SORTED=()
local elem
while IFS= read -r -d '' elem ; do
SORTED+=("$elem")
done < <(printf '%s\0' "$@" | sort -z)
}
(Note the use of null bytes as a delimiter, rather than newlines, so that your array elements are unrestricted. This is achieved by the -d ''
option to read
, the \0
in the printf
format-string, and the -z
option to sort
.)
It can be used like this:
arr=('a b c' 'd e f' 'b c d' 'e f g' 'c d e')
printf '%s\n' "${arr[@]}" # prints elements, one per line
sort_array "${arr[@]}"
arr=("${SORTED[@]}")
printf '%s\n' "${arr[@]}" # same as above, but now it's sorted
Upvotes: 2