syker
syker

Reputation: 11272

Sorting space delimited numbers with Linux/Bash

Is there a Linux utility or a Bash command I can use to sort a space delimited string of numbers?

Upvotes: 27

Views: 30959

Answers (9)

Jeremy Moritz
Jeremy Moritz

Reputation: 14892

I added this to my .zshrc (or .bashrc) file:

#sort a space-separated list of words (e.g. a list of HTML classes)
sortwords() {
  echo $1 | xargs -n1 | sort -g | xargs
}

Call it from the terminal like this:

sortwords "banana date apple cherry"

# apple banana cherry date

Thanks to @FranMowinckel and others for inspiration.

Upvotes: 1

user256717
user256717

Reputation:

$ awk 'BEGIN{split(ARGV[1], numbers);for(i in numbers) {print numbers[i]} }' \
     "6 7 4 1 2 3" | sort -n

Upvotes: 0

FranMowinckel
FranMowinckel

Reputation: 4343

This is a variation from @JamesMorris answer:

echo "81 4 6 12 3 0" | xargs -n1 | sort -g | xargs

Instead of tr, I use xargs -n1 to convert to new lines. The final xargs is to convert back, to a space separated sequence of numbers.

Upvotes: 15

James Morris
James Morris

Reputation: 4935

Here's a simple example to get you going:

echo "81 4 6 12 3 0" | tr " " "\n" | sort -g

tr translates the spaces delimiting the numbers, into carriage returns, because sort uses carriage returns as delimiters (ie it is for sorting lines of text). The -g option tells sort to sort by "general numerical value".

man sort for further details about sort.

Upvotes: 45

bashfu
bashfu

Reputation: 1

Improving on Evan Krall's nice Bash "array sort" by limiting the scope of IFS to a single command:

printf "%q\n" "${IFS}"
array=(3 2 11 15 8) 
array=($(IFS=$'\n' sort -n <<< "${array[*]}")) 
echo "${array[@]}" 
printf "%q\n" "${IFS}"

Upvotes: 0

Evan Krall
Evan Krall

Reputation: 3126

If you actually have a space-delimited string of numbers, then one of the other answers provided would work fine. If your list is a bash array, then:

oldIFS="$IFS"
IFS=$'\n'
array=($(sort -g <<< "${array[*]}"))
IFS="$oldIFS"

might be a better solution. The newline delimiter would help if you want to generalize to sorting an array of strings instead of numbers.

Upvotes: 0

trevvor
trevvor

Reputation: 11

Using Bash parameter expansion (to replace spaces with newlines) we can do:

str="3 2 11 15 8" 
sort -n <<< "${str// /$'\n'}"

# alternative
NL=$'\n'
str="3 2 11 15 8"
sort -n <<< "${str// /${NL}}"

Upvotes: 1

Dennis Williamson
Dennis Williamson

Reputation: 359965

This is a variation on ghostdog74's answer that's too big to fit in a comment. It shows digits instead of names of numbers and both the original string and the result are in space-delimited strings (instead of an array which becomes a newline-delimited string).

$ s="3 2 11 15 8"
$ sorted=$(echo $(printf "%s\n" $s | sort -n))
$ echo $sorted
2 3 8 11 15
$ echo "$sorted"
2 3 8 11 15

If you didn't use the echo when setting the value of sorted, then the string has newlines in it. In that case echoing it without quotes puts it all on one line, but, as echoing it with quotes would show, each number would appear on its own line. This is the case whether the original is an array or a string.

# demo
$ s="3 2 11 15 8"
$ sorted=$(printf "%s\n" $s | sort -n)
$ echo $sorted
2 3 8 11 15
$ echo "$sorted"
2
3
8
11
15

Upvotes: 4

ghostdog74
ghostdog74

Reputation: 342323

$ s=(one two three four)
$ sorted=$(printf "%s\n" ${s[@]}|sort)
$ echo $sorted
four one three two

Upvotes: 3

Related Questions