1

I have been trying to sort specific columns with some data I have which is:

ID Name Last Grade      
123 Bill Holy A   
747 Chloe Crown B    
757 Aaron Farmer D    
365 Gray Billson

Column by column I'm trying to sort the first column (ID) in numerical order, sort the second column (Name) in alphabetical order while all other peices of data are left as they are. I'd like to do this in one whole command. So far I have tried sort -k1,1 -k2,2 [filename], but all this did was sort the first column in numerical order but the second column (Name) did not appear to have changed or have been sorted in anyway. Lastly when I ran this command it made the headers (ID, Name, Last, Grade) move to the bottom.

2 Answers 2

3

Your example containes unique field 1 values (the ID number) so if the data is sorted by ID, subsequently sorting by name will have no effect.

The sort program sorts the entire file, without looking for header lines...

The following Awk program prints the header line, and sends all subsequent lines to sort.

awk '{if (NR==1) {print $0} {print $0 | "sort -k1,1 -k2,2"}}' <filename>
13
  • head -n1 <filename>; tail +2 <filename> | sort -k1,1n -k2,2
    – Michael D.
    Commented Feb 16, 2019 at 18:20
  • @MichaelD. Two ways to skin a cat Commented Feb 16, 2019 at 18:24
  • @MichaelD.- on a GNU system that could further be simplified to { head -n1; sort -k1,1 -k2,2; } < file_name
    – iruvar
    Commented Feb 17, 2019 at 0:52
  • @iruvar That works in bash - but why? Commented Feb 17, 2019 at 0:57
  • @CharlesGreen, that's because when the input file is seekable(like in this case), GNU head ensures the file offset in the open file description is properly positioned past the last byte that was processed (so in this particular instance head leaves the file offset at the beginning of line 2 thereby teeing things up nicely for sort). BTW, shouldn't your awk solution be doing a {print $0; next} instead of just a {print $0} when NR ==1?
    – iruvar
    Commented Feb 17, 2019 at 1:08
0

With gnu sed and sort :

sed -z 'h;s/\n.*//;x;s/[^\n]*\n//;s/.*/echo "&"|sort -k1,1 -k2,2/e;x;G' infile

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .