Using Raku (formerly known as Perl_6)
Adding this answer for U&L users who might be trying to sorting Unicode. Raku has high-level support for Unicode built-in, and this answer (in part) is to help this author understand Raku's sorting rules.
Sorting on one column (last-name) with a 'unary' comparison operator/block (commented out at top), or with a binary block containing the leg "less-than/equal-to/greater-than" string comparison operator. Ties stay in 'encounter' order (i.e. stable sort):
~$ #`{ raku -e '.put for lines.sort: { .words[1] };' #unary block, OR binary block below: } ~$ raku -e '.put for lines.sort: { $^a.words[1] leg $^b.words[1] };' file Tony Bedford 50 James Bedford 21 Emily Bedford 18 Fred Bloggs 22 Pete Brown 37 Mark Brown 46 Francis Chepstow 56 Stefan Heinz 52 Simon Strange 62 John Strange 51 Ana Villamor 44 Alice Villamor 50
Sorting on two columns, last-name then first-name. At top (commented out), giving sort a list of unary elements to sort on. Second example below: more explicitly using two leg string-comparison operators, with || "short-circuit-OR" in between:
~$ #`{ raku -e '.put for lines.sort: { .words.[1], .words.[0] }; #list of unary elements, OR binary blocks below: } ~$ raku -e '.put for lines.sort: {$^a.words[1] leg $^b.words[1] || $^a.words[0] leg $^b.words[0] };' file Emily Bedford 18 James Bedford 21 Tony Bedford 50 Fred Bloggs 22 Mark Brown 46 Pete Brown 37 Francis Chepstow 56 Stefan Heinz 52 John Strange 51 Simon Strange 62 Alice Villamor 50 Ana Villamor 44
The above Raku code satisfies the title of this question: "Trying to sort on two fields, second then first". But if one column is numeric you can use<=> instead of leg to sort numerically (<=> is commonly termed 'spaceship' operator). Example below:
The following sorts on three (3) columns: last-name, reverse age (oldest first--swap $^b and $^a for reverse sort), then first-name. So in the sorted output Simon Strange 62 will appear before John Strange 51.
Raku has an improved cmp operator which tries to detect Types and make smart comparisons for you (i.e. string comparisons with leg and numeric comparisons with <=>). In the second example below, three cmp comparisons give the exact same sorted output as the first example:
~$ #`{ raku -e '.put for lines.sort: {$^a.words[1] leg $^b.words[1] || $^b.words[2] <=> $^a.words[2] || $^a.words[0] leg $^b.words[0] };' #OR with cmp operator below: } ~$ raku -e '.put for lines.sort: {$^a.words[1] cmp $^b.words[1] || $^b.words[2] cmp $^a.words[2] || $^a.words[0] cmp $^b.words[0] };' file Tony Bedford 50 James Bedford 21 Emily Bedford 18 Fred Bloggs 22 Mark Brown 46 Pete Brown 37 Francis Chepstow 56 Stefan Heinz 52 Simon Strange 62 John Strange 51 Alice Villamor 50 Ana Villamor 44
Finally, the "binary comparator blocks" (above) can give you a precise understanding/control over your sorting mechanism. But if you prefer, sorting on three columns (above) can be simplified to the code below:
~$ raku -e '.put for lines.sort: { ~.words[1], -.words[2], ~.words[0] };' file Tony Bedford 50 James Bedford 21 Emily Bedford 18 Fred Bloggs 22 Mark Brown 46 Pete Brown 37 Francis Chepstow 56 Stefan Heinz 52 Simon Strange 62 John Strange 51 Alice Villamor 50 Ana Villamor 44
https://perl6advent.wordpress.com/2013/12/23/day-23-unary-sort/ https://docs.raku.org/language/101-basics#Stable_sort
https://docs.raku.org/routine/sort
https://docs.raku.org/routine/cmp
https://perl6advent.wordpress.com/2013/12/23/day-23-unary-sort/
https://raku.org