Sorting – How to Numerically Sort a Single Line of Delimited Items

numeric datasort

I have a line (or many lines) of numbers that are delimited by an arbitrary character. What UNIX tools can I use to sort each line's items numerically, retaining the delimiter?

Examples include:

  • list of numbers; input: 10 50 23 42; sorted: 10 23 42 50
  • IP address; input: 10.1.200.42; sorted: 1.10.42.200
  • CSV; input: 1,100,330,42; sorted: 1,42,100,330
  • pipe-delimited; input: 400|500|404; sorted: 400|404|500

Since the delimiter is arbitrary, feel free to provide (or extend) an Answer using a single-character delimiter of your choosing.

Best Answer

With gawk (GNU awk) for the asort() function:

gawk -v SEP='*' '{ i=0; split($0, arr, SEP); len=asort(arr);
    while ( ++i<=len ){ printf("%s%s", i>1?SEP:"", arr[i]) }; 
        print "" 
}' infile

replace * as the field separator in SEP='*' with your delimiter.



You can also do with the following command in case of a single line (because it's better leave it alone of using shell-loops for text-processing purposes)

tr '.' '\n' <<<"$aline" | sort -n | paste -sd'.' -

replace dots . with your delimiter.
add -u to the sort command above to remove the duplicates.

Notes:
You may need to use -g, --general-numeric-sort option of sort instead of -n, --numeric-sort to handle any class of numbers (integer, float, scientific, Hexadecimal, etc).

$ aline='2e-18,6.01e-17,1.4,-4,0xB000,0xB001,23,-3.e+11'
$ tr ',' '\n' <<<"$aline" |sort -g | paste -sd',' -
-3.e+11,-4,2e-18,6.01e-17,1.4,23,0xB000,0xB001

In awk no need change, it still will handling those.