How to sort a list of numbers and null values in ascending order, with null values at the end?

0

I have a list of numbers and null values. How can I sort them in a way such that the null values come to the end of the list using sort in GNU coreutils?

Sample Input (input.data)

0.9000
23

1
2
5

-0.9000
-23

-1
-2
-5

When I tried to with sort -g input.data, the output is as follows.

<NULL>
<NULL>
<NULL>
-23
-5
-2
-1
-0.9000
0.9000
1
2
5
23

Here null values are placed at the top. Is it possible to get the null values to the end of the list?

Ishan Madhusanka

Posted 2018-10-16T10:13:01.437

Reputation: 273

Answers

2

I assume your null values are just empty lines.

If your only requirement is that the empty lines are at the end, then simply reverse the order, of course this will also change the order of the numbers. Here are some variants side by side:

$ sort -g file           $ sort -gr file          $ sort -r file
                         23                       5
                         5                        -5
                         2                        23
-23                      1                        -23
-5                       0.9000                   2
-2                       -0.9000                  -2
-1                       -1                       1
-0.9000                  -2                       -1
0.9000                   -5                       0.9000
1                        -23                      -0.9000
2                                                 
5                                                 
23                                                

If the order of the numbers has to be sort -g and only the empty lines should move to the end you could simple remove all empty lines and paste them at the end.

grep . file | sort -g | cat - <(grep -v . file)

Socowi

Posted 2018-10-16T10:13:01.437

Reputation: 161

1

Create an extra column and sort by it first, remove it at the end:

<input.data sed 's/^/1 /; s/^1 $/2 /' | sort -k 1n -k 2g | sed 's/^. //'

The advantage is the command reads its input just once, so you can use it in a pipe.

Explanation:

  1. The first sed adds 1 (note the trailing space) in front of every line. If 1 is now the whole line (which means the original line was empty), it will be replaced by 2 . This creates an extra column that indicates whether the original line was empty or not.
  2. sort is told to sort according to the first (extra) column, only then according to the second.
  3. The final sed removes whatever the first one added.

Note:

  • In general sort uses locale (details). I deliberately chose digits 1 and 2 and numerical sort to make the whole trick work in any(?) sane western locale.

Kamil Maciorowski

Posted 2018-10-16T10:13:01.437

Reputation: 38 429