Sort by multiple columns in bash

41.7k views Asked by At

I have a file with 2 columns, "Name" and "Age", looking like this:

Alex,  15
Mary,  12
Alex,  28
Zoe,   16
Alex,  17

I will sort by the first column in alphabetical order, using sort -t ',' -k1,1 filename.txt, but if there are same names, I want the 2nd column to be sorted in the reversed way of how they were in the original file, like this:

Alex,  17
Alex,  28
Alex,  15
Mary,  12
Zoe,   17

How can I do this?

5

There are 5 answers

1
piarston On

This should gives what you want:

sort -k1,1 -k2,2 filename.txt
0
piarston On

Wops it seems I misunderstood your problem. I cannot find of a magic command, but a little script might do the job:

#! /bin/bash
declare names_sorted=$(cut -d, -f1 filename.txt | sort -k1,1 | uniq)
for name in $names_sorted ; do
    grep "$name," filename.txt | tac
done

Quick explanation:

  1. first we assemble the sorted list of names: $names_sorted.
  2. next (assuming the names do not contain white-spaces), we grep each name from the original list and revert that order with the command tac

Hope it's what you wanted this time ;-)

0
Tomáš Šíma On

Read file from back, sort by the first column and -s to preserve order in case of same value

tac filename.txt | sort -k1,1 -s
...
Alex,  17
Alex,  28
Alex,  15
Mary,  12
Zoe,   16
0
Jojo Thomas On
tac filename.txt | sort -t"," -k1,1 -s

Explanation:

  • tac will sort the output in reverse order.
  • -t"," defines the field delimiter.
  • -k1,1 limits the sorting column to the first one only.
  • -s preserves the order within the sorted rows.
1
lqxyz On
sort -t ',' -k1,1 -k2,2r filename.txt

or

sort -t ',' -k1,1 -k2r,2 filename.txt

The output is:

Alex,  28
Alex,  17
Alex,  15
Mary,  12
Zoe,   16

Explain: -t is to specify the field-separator, -k can be used to specify the start and stop position of field, and we could add a single letter OPTS for that field for ordering, for example r means to reverse the result of comparisons.