spring cc
spring cc

Reputation: 1027

how to sort the line of a file by to the second word from the end

I want to sort the line accorfing to the last number just before the space. And this is a simplified example:

c3_abl_eerf_14 sasw
a.bla_haha_2 dnkww
s.hey_3 ddd

And this is the results I want:

a.bla_haha_2 dnkww
s.hey_3 ddd
c3_abl_eerf_14 sasw

I don't know how to do this, maybe by the command sort? And, sometimes I used the sort command, it may wrongly treat the 14 less than 2, I don't want this to happen.

Upvotes: 7

Views: 1106

Answers (2)

Kent
Kent

Reputation: 195209

this command chain works for your example:

sed -r 's/.*_([0-9]+) .*/\1 &/' file|sort -n|sed 's/[^ ]* //'

The idea is

  • extract the number first, add to the beginning of the line
  • sort all lines by this number
  • remove the number

update

sort by last number in the line, no matter where the number is:

awk -F'[^0-9]+' '{$0=(length($NF)?$NF:$(NF-1)) OFS $0}7' file|sort -n|sed 's/[^ ]* //'

Upvotes: 9

Michael Vehrs
Michael Vehrs

Reputation: 3363

If you want to do it with GNU awk, try this:

BEGIN { FS = "[ _]+" }
{ data[$(NF-1)] = data[$(NF-1)] "\n" $0}
END {
    n = asorti(data, sorted, "@val_num_asc");
    for (i = 1; i <= n; i++) {
        print substr(data[sorted[i]], 2);
    }
}

This works as follows: The BEGIN rule sets the field separator (you could also do this on the command line). The second rule applies to all lines of the input and puts them into an associative array indexed by the number in the second but last field. The END rule sorts the indices of this array into a second array, and the following loops prints the values, now sorted.

Upvotes: 7

Related Questions