Read in all the records into an array of hashes. Then you can decide how to re-format/sort them them.
Here's a simple parser based on what your format seems to be:
my @list;
while (<>) {
chomp;
my (%hash, @rest);
($hash{first}, $hash{date}, @rest) = split(",", $_);
for my $r (@rest) {
my ($k, $v) = split(' ', $r, 2);
$hash{$k} = $v;
}
push(@list, \%hash);
}
Now it doesn't matter what order the fields are in. To determine all the fields present in any of the records, you can use:
my %seen;
for (@list) { for (keys %$_) { $seen{$_}++ } };
delete $seen{first};
delete $seen{date};
my @allkeys = ('first', 'date', sort keys %seen);
I'm just assuming that you want the first two fields to remain where they are. The rest will be sorted alphabetically.