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
  • 1
    you have an error in your expected output in position 2.2 Dec 14, 2016 at 12:16

4 Answers 4

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.)

2
  • 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-. Dec 14, 2016 at 14:55
  • awk '{ k= $1>$2 ? $1: $2 ; print k, $0 }'
    – JJoao
    Dec 14, 2016 at 16:55
0

For Numerical Sort in the Two first columns

sort -n -t " " -k1,1 -k2,2 /path/to/file
4
  • what is the point of -t here ? Dec 14, 2016 at 12:28
  • to specify the separator ^^ Dec 14, 2016 at 12:32
  • I know but it's not necessary here Dec 14, 2016 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, 2016 at 16:25
0

You can do that with GNU sort:

sort -k1,1n -k2,2n yourfile
  • -k for specify the column
1
  • 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, 2016 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] }
}

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.