#Foreach that loops through @rows which stores data from a CSV file. foreach my $rec (@rows) { foreach my $dept (@Divisions) { if ($rec->[5] =~ /^$dept/ && $rec->[8] =~ /^P\W[1-5]|D\W[1-2]|AD\w|DD\w|DG/) { my $Rec = { GRADE=>strip_hyphen($rec->[0]), POSITION=>$rec->[1], NAME=>invert_name($rec->[2]) }; #The Divison is then added here push @{$AG{$rec->[4]}},$Rec; } } } Dump of the %AG structure generated by logic above: VAR1 = 'ESRD - Office of Director'; $VAR2 = [ { 'NAME' => 'A. Smith', 'POSITION' => 'DIRECTOR', 'GRADE' => 'D1' }, { 'NAME' => 'P. Green', 'POSITION' => 'SENIOR DIRECTOR', 'GRADE' => 'D2' } ]; $VAR3 = 'BERF - Office of Technology'; $VAR4 = [ { 'NAME' => 'G. Tekola', 'POSITION' => 'JUNIOR OFFICER', 'GRADE' => 'P1' }, { 'NAME' => 'P. Brown', 'POSITION' => 'JUNIOR OFFICER', 'GRADE' => 'P1' }, { 'NAME' => 'T. Green', 'POSITION' => 'Technology Officer', 'GRADE' => 'P2' }, { 'NAME' => 'T. Green', 'POSITION' => 'Technology Officer', 'GRADE' => 'P2' }, { 'NAME' => 'T. Green', 'POSITION' => 'Technology Chief', 'GRADE' => 'P3' }, ]; #### foreach my $A (sort keys %AG) { foreach my $p ( sort { substr($$a{GRADE},0,1) cmp substr($$b{GRADE},0,1) || substr($$b{GRADE},0,2) cmp substr($$a{GRADE},0,2)} @{$AA{$A}}) { my( $grade_nums,$grade, $name,$position ) = ($p->{GRADE_NUMS},$p->{'GRADE'}, $p->{'NAME'},$p->{'POSITION'} ); print $grade_nums,$grade, $name,$position,"\n"; } }