0

I have a file that contains:

1 1 1 1 text1
7 9 4 2 text2
2 2 0.5 0.7 text3
5 4 1 2 text4

I want to sort it (output to the terminal) according to the maximum of the first two columns.

expected output:

1 1 1 1 text1
2 1 0.5 0.7 text3
5 4 1 2 text4
7 9 4 2 text2

how can this be achieved? thanks!

  • 1
    you have an error in your expected output in position 2.2 – Wissam Roujoulah Dec 14 '16 at 12:16
2

Your input file is:

1 1 1 1 text1
7 9 4 2 text2
2 2 0.5 0.7 text3
5 4 1 2 text4

With this input a simple sort will work:

$ sort << EOF
> 1 1 1 1 text1
> 7 9 4 2 text2
> 2 2 0.5 0.7 text3
> 5 4 1 2 text4
> EOF
1 1 1 1 text1
2 2 0.5 0.7 text3
5 4 1 2 text4
7 9 4 2 text2

If we amend the input to something like...

$ cat test.txt
1 3 1 1 text1
7 9 4 2 text2
2 1 0.5 0.7 text3
5 4 1 2 text4

Then the input becomes challenging. A simple sort no longer works, and we can test other approaches:

$ sort -k1,1n -k2,2n < test.txt
1 3 1 1 text1
2 1 0.5 0.7 text3
5 4 1 2 text4
7 9 4 2 text2

This isn't what we'd expect - The first two lines of output are reversed - the highest 1/2 column value in line 1 is "3", and the highest in line 2 is "2".

The following appears to work, at least for the revised input file, but it's not pretty (my awk-fu is weak):

$ awk '{ sorton=$1; if ($2>$1) { sorton=$2 }; print $1, $2, $3, $4, $5, sorton }' < test.txt | sort -k 6 | cut -d " " -f 1-5
2 1 0.5 0.7 text3
1 3 1 1 text1
5 4 1 2 text4
7 9 4 2 text2

@Nominal-Animal and @JJoao suggested refinements, resulting in:

$ awk '{ k= $1>$2 ? $1: $2 ; print k, $0 }' test.txt | sort -g | cut -d ' ' -f 2-
2 1 0.5 0.7 text3
1 3 1 1 text1
5 4 1 2 text4
7 9 4 2 text2

(Feel free to edit this post to refine an awk solution.)

| improve this answer | |
  • 2
    You could use awk '{ if ($1 >= $2) k = $1 ; else k = $2 ; printf "%s %s\n", k, $0 }' test.txt | sort -g | cut -d ' ' -f 2-. – Nominal Animal Dec 14 '16 at 14:55
  • awk '{ k= $1>$2 ? $1: $2 ; print k, $0 }' – JJoao Dec 14 '16 at 16:55
0

For Numerical Sort in the Two first columns

sort -n -t " " -k1,1 -k2,2 /path/to/file
| improve this answer | |
  • what is the point of -t here ? – Wissam Roujoulah Dec 14 '16 at 12:28
  • to specify the separator ^^ – Hamza Jabbour Dec 14 '16 at 12:32
  • I know but it's not necessary here – Wissam Roujoulah Dec 14 '16 at 12:48
  • I'm not sure this addresses the requirement of sorting by the largest value of the first two columns; your answer sorts by column 1 and only if column1 is equal does it use column 2. – Jeff Schaller Dec 14 '16 at 16:25
0

You can do that with GNU sort:

sort -k1,1n -k2,2n yourfile
  • -k for specify the column
| improve this answer | |
  • I'm not sure this addresses the requirement of sorting by the largest value of the first two columns; your answer sorts by column 1 and only if column1 is equal does it use column 2. – Jeff Schaller Dec 14 '16 at 16:25
0

If you have GNU awk (gawk) as your awk, you can use its asort() function to do everything inside of awk itself:

{
  max = $1 > $2 ? $1 : $2;
  if (max in lines)
    lines[max] = lines[max] ORS $0
  else
    lines[max] = $0
}

END {
  asort(lines, lines, "@ind_num_asc")
  for(i=1; i<=length(lines); i++) { print lines[i] }
}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.