Home > OS >  Sorting multiple columns with delimiter "." in bash
Sorting multiple columns with delimiter "." in bash

Time:06-22

I'm trying to sort a list of text that looks like this:

2023.12.14
2020.10.4
2020.10.1
2020.5.18
2023.14.1
2021.1.1

desired output:

2020.5.18
2020.10.1
2020.10.4
2021.1.1
2023.12.14
2023.14.1

I tried to achieve it with the following command:

sort -t "." -k1,1 -k2,1 -k3,1 sortingTest.txt

With this command I'm trying to sort it by the first "column" (anything before the delimiter "."), and in case that two values are equal than compare the values of the second column etc.

For some reason it only sorts by comparing values of the first column.

What am I missing?

CodePudding user response:

Think that sort -V sorts your data as you want:

$ echo '2023.12.14
> 2020.10.4
> 2020.10.1
> 2020.5.18
> 2023.14.1
> 2021.1.1' | sort -V

2020.5.18
2020.10.1
2020.10.4
2021.1.1
2023.12.14
2023.14.1

CodePudding user response:

You got a few problems, the -k is defined as: -kfield1[,field2], which means -k2,1 is invalid. You can use -k1 -k2 -k3 to sort on the first three fields.

You properly want to do numeric sort on your fields, this can be enabled with -n see man 1 sort for other numeric sorting options:

$ sort -t. -n -k1 -k2 -k3 file.txt
2020.5.18
2020.10.1
2020.10.4
2021.1.1
2023.12.14
2023.14.1

Might work for you.

In case these are actually versions and not dates, then -V might be sufficient.

CodePudding user response:

AFAIK the only way this can be done with only sort is to use -V. But -V is not POSIX, and is not available in some sort implementations. So here's a POSIX (portable) solution:

awk -F . '{printf "d.d.d\n", $1,$2,$3}' dates-file |
sort |
awk -F . '{printf "%d.%d.%d\n", $1,$2,$3}'

awk transforms the fields to fixed length for sorting, then again transforms sorted data to the original format. This assumes these are dates.

  • Related