That's kind of an interesting problem. As such, I've written a solution, even though you haven't shown any work. My solution could be a lot more readable, but it does the job. Some explanation is in the comments.
#!/usr/bin/perl
use strict;
use warnings;
my $op_io = <<'OP_INPUT_AND_OUTPUT';
'aaa' 1,2 'aaa' 1,2
'aaa' 2,1 'aaa' 2,3
'aaa' 2,3 'aaa' 2,1
'aaa' 3,1 'aaa' 3,1
'aaa' 3,2 'aaa' 3,2
'aaa' 4,1 'aaa' 4,5
'aaa' 4,5 'aaa' 4,1
'bbb' 2,2 'bbb' 2,1
'bbb' 2,5 'bbb' 2,2
'bbb' 2,1 'bbb' 2,5
'bbb' 4,3 'bbb' 4,6
'bbb' 4,6 'bbb' 4,3
'bbb' 4,1 'bbb' 4,2
'bbb' 4,2 'bbb' 4,1
'ccc' 3,3 'ccc' 1,1
'ccc' 3,6 'ccc' 1,3
'ccc' 1,3 'ccc' 2,4
'ccc' 1,1 'ccc' 2,2
'ccc' 6,4 'ccc' 3,3
'ccc' 6,6 'ccc' 3,6
'ccc' 2,2 'ccc' 6,6
'ccc' 2,4 'ccc' 6,4
OP_INPUT_AND_OUTPUT
;
my @init;
my @want;
my $n = 0;
foreach my $line ( split /\n/, $op_io ) {
( $init[$n][0], $init[$n][1], $init[$n][2],
$want[$n][0], $want[$n][1], $want[$n][2] )
= ( $line =~ m{ \A \'(...)\' \s+ (\d+),(\d+)
\s+ \'(...)\' \s+ (\d+),(\d+) }xms );
$n++;
}
# At this point, @init and @want are both AoA.
# unique X values for each group
my %x_of;
$x_of{$_->[0]}{$_->[1]}++ for @init;
# map an X to its relative position in a sorted list of X.
foreach my $group ( keys %x_of ) {
my @exez = sort { $a <=> $b } keys %{ $x_of{$group} };
@{ $x_of{$group} }{@exez} = 0 .. $#exez;
}
# Sort first by group, then by X,
# then ascending or descending depending on what X's position is.
my @out = sort { $a->[0] cmp $b->[0]
||
$a->[1] <=> $b->[1]
||
( ( $x_of{ $a->[0] }{ $a->[1] } % 2 )
? ( $b->[2] <=> $a->[2] )
: ( $a->[2] <=> $b->[2] ) )
} @init;
use Test::More tests => 1;
is_deeply( \@out, \@want, 'it works!' );