in reply to sorting question

Perhaps an explanation of how kabel's code works might help you understand where you went wrong. It's a little different from your version but they have similar principles behind them.
$str = join "\n", map { $_->[0] } sort {$a->[THIRD_FIELD] cmp $b->[THIRD_FIELD] } map { [$_, split('\|', $_)] } split(/\n/, $str);

So, how does the schwartzian transform work? First you'll have to realise that the code works from the bottom up, essentially, so this description will have to do so too.

split(/\n/, $str);
This is easy. $str is a huge string of lines joined with newlines. This splits it up so we have a list of lines.

map { [$_, split('\|', $_)] } split(/\n/, $str);
Well... split('\|', $_) breaks up a given line on the pipe (|) character. So "abc|123|cde" becomes a list of ("abc", 123, "cde");

Now [$_, split('\|', $_)] creates a list with the original string ($_) and then our split up version. So we'd get: ("abc|123|cde", "abc", 123, "cde") from our line above. Map does this across all elements of the following list, so we end up with an list of lists; for example:

( ["abc|123|cde", "abc", 123, "cde"], ["def|222|eee", "def", 222, "eee +"])
Easy so far.

sort {$a->[THIRD_FIELD] cmp $b->[THIRD_FIELD] }
This carries out our sort over the list we've created with the previous map. Note that we can pick which field to sort by, by changing the value. If you wanted to sort by several keys you might do something like:
sort {$a->[THIRD_FIELD cmp $b->[THIRD_FIELD] || $a->[FIRST_FIELD cmp $b->[FIRST_FIELD]}
cmp returns 0 if the compare is the same so then the other side of the or will be evalated.

join "\n", map { $_->[0] }
Remember that we have a list of lists at this point and the first element of each sublist is the original string. This map merely discards all the other elements of each sublist, keeping the original string. We then join them each with a newline.

I hope that helps you understand how it's supposed to work.

jarich