Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello. I have a file
00018066: 13:33:19,Routd,15444,,3678800,0,,,7086 00018066: 13:33:19,Alert,15444,,3678800,0,,7086 00018066: 13:33:20,Cnnct,15444,,3678800,0,,7086 00018066: 13:33:20,Cnnct,15445,,3678800,0,,7086 00018066: 13:33:41,Routd,15444,,3678800,0,,7086,7800 00018066: 13:33:21,Routd,15444,,3678800,0,,7086,7801
I am trying to sort this based on the time (in the format hh:mm:ss). I have some conditions to check for and trying to display this so that it is in chronological order. Here is what I have so far...
#!/usr/bin/perl print "Please enter trace file name\n"; $tracefilename = <STDIN>; chomp $tracefilename; print "Please enter agent extension\n"; $agentextension = <STDIN>; chomp $agentextension; while (1) { print "Please enter time in 24 hour (e.g 1:00 PM would be 13:00:00 +)\n"; $time = <STDIN>; chomp $time; if ($time =~/^(\d\d):(\d\d):(\d\d)/ ) { $phour = $1; $pmin = $2; $psec = $3; last; } # loop if incorrect format print "Incorrect time format. Please re-enter time in military fo +rmat.\n"; } # print a spaces for better viewing print "\n"; print "\n"; #open tracefilename open (THATFILE, "$tracefilename") or die "cannot open $tracefilename: $!"; #read each line of file and grab line that has associated agent extens +ion and time LINE: while (<THATFILE>) { next LINE if (!/^\d+: (\d\d):(\d\d):(\d\d)/ ); chomp ($_); # print "line = $_\n"; # look for agent extension in positions 6, 7, or 8 in trace line ($ext,$toext,$spext)=(split(/,/,$_))[6..8]; if( $ext==$agentextension or $toext==$agentextension or $spext==$agentextension) { ($hour,$min,$sec)=($1,$2,$3); $diffhour = 3600 * ($phour - $hour); $diffmin = 60* ($pmin - $min); $diffsec = ($psec - $sec); $sumdiff = abs ($diffhour) + abs ($diffmin) + abs ($di +ffsec); if ($sumdiff <= 2) { ($callid)=(split(/,/,$_))[2]; next LINE; #I want to keep track of each callid associated with agent extensi +on and 2 second time stamp. #I noticed that the callid is in the 4th position } } } # reset filehandle to offset 0 from start of file (0) seek (THATFILE, 0, 0); # second loop to file, grabbing lines with associated CallID in 4th po +sition. LOOP: while (<THATFILE>) { chomp ($_); ($pos4) = (split(/,/,$_)) [2]; if ($pos4 == $callid) { push (@array, $_."\n"); next LOOP; } } #sort array (@array) by time and line number print @array; close (THATFILE);
The script should basically accept a time and calculate against this file anything with a 2 second time difference. It must also verify that the 'agent extension' is in the correct position and once both conditions are met, it will grab the keep track of the 'call id'. For the second pass, labeled LOOP, I want to print each line with the call id. I need to sort this based on the time. I can't assume that the time will always be on the file in the right order. I've split the fields for hours, minutes, and seconds and need to sort based on hour, minute and seconds...What is the best way to do this!? THANKS in advance!!

Replies are listed 'Best First'.
Re: sorting
by Hot Pastrami (Monk) on Mar 22, 2001 at 02:38 UTC
    When you sort an array, you can provide a block of code which specifies how the items are compared. The items are handed to the block two by two as $a and $b. To compare numbers, use "<=>", and to compare strings use "cmp". The syntax basically looks like this:
    @array = sort { $a <=> $b } @array;
    So if the array was an array of hashes and you wanted to sort by the "time" fields, it would look a lot like this:
    @array = sort { $a->{time} <=> $b->{time} } @array;
    ..or to sort in reverse order...
    @array = sort { $b->{time} <=> $a->{time} } @array;
    ..or to sort as strings (non case-sensitive)...
    @array = sort { uc $a->{time} cmp uc $b->{time} } @array;
    Hopefully this will give you enough information to figure it out.

    Hot Pastrami