On Thu, 2006-11-09 at 08:47 -0500, Zielfelder, Robert wrote: > Greetings: > > > > I have a sorting problem I need to solve but I'm not sure how to go > about it. I have an application that dumps a file with a format like > this: > > > > 19JAN2006.1503 > > 03JAN2006.1647 > > 19DEC2004.0530 > > 24MAR2003.1115 > > > > > > As you may have guessed, these are dates and times - timestamps for log > files from an application. I want to be able to sort this list from > earliest to latest date. I'm able to parse these into specific > categories (Year, Month, Day, Time) and can sort on any one category, > but I don't know how to sort by multiple categories. Anyone have any > ideas? > > > > Thanks, > > > > Rz
I know some Perl mongers have already answered this. Though I've seen some non-satisfying ways in the examples. Now, I'm not saying my way is the best way, but it's a real multilevel sort. You can indeed have a multilevel sort. So here's how I would have done it: --- Begin code --- #!/usr/bin/perl -w use strict; my @files = qw( 19JAN2006.1503 03JAN2006.1647 25DEC2001.0001 19DEC2004.0530 24MAR2003.1115 21MAY2003.0554 ); my %files_date; for (@files) { $files_date{$_} = [/(\d{2})(.{3})(\d{4})\.?(\d{4})/]; } ## the code below is used so that you can see ## the values of each key in the %files_date hash: #for my $key (keys %files_date) { # for my $value (@{$files_date{$key}}) { # print "$key => $value\n"; # } #} my @sorted_files = sort { $files_date{$a}[2] <=> $files_date{$b}[2] # by year or $files_date{$a}[1] cmp $files_date{$b}[1] # by month or $files_date{$a}[0] <=> $files_date{$b}[0] # by day or $files_date{$a}[3] cmp $files_date{$b}[3] # by time } keys %files_date; for (@sorted_files) { print "$_\n"; } --- End of code --- --- Output --- 25DEC2001.0001 24MAR2003.1115 21MAY2003.0554 19DEC2004.0530 03JAN2006.1647 19JAN2006.1503 -- End of output --- Now, that is a multilevel sort. You can rearrange it to suit your needs, sort it by time first or by month, whatever you wish. If you wish the youngest files to show up first, all you have to do is "reverse" the sort by checking $b before $a, there's no need for the reverse operator. Example: --- Code --- my @sorted_files = sort { $files_date{$b}[2] <=> $files_date{$a}[2] # by year or $files_date{$b}[1] cmp $files_date{$a}[1] # by month or $files_date{$b}[0] <=> $files_date{$a}[0] # by day or $files_date{$b}[3] cmp $files_date{$a}[3] # by time } keys %files_date; --- End of code --- --- Output --- 03JAN2006.1647 19JAN2006.1503 19DEC2004.0530 24MAR2003.1115 21MAY2003.0554 25DEC2001.0001 --- End of output --- See the difference? Compare the two (both the code and the output). The possibilities are endless. :-) Of course my code assumes you have at least a basic knowledge of references, see "perldoc perlreftut" or go to http://perldoc.perl.org/perlreftut.html . For the on-line documentation. I can explain my solution in full detail if you'd like. I'll be more than happy to do so. :-) -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>