#!/usr/bin/perl -w #) { chomp; # Store each log entry in the array. if (/($retimestamp)(.*)/o) { $found = 1; if (length($stamp)) { # previous entry is done, save it. push @logfile, { stamp => "$stamp", user => "$user", entry => "$entry" }; } $stamp = $1; $user = $2; $entry = ''; } else { if ($found) { # Contents of a given log-entry. $entry .= "$_\n"; } else { # No timestamp found yet. print "$_\n"; } } } # If we hit eof and we've read at least one timestamped entry, # it hasn't been stored yet. If we haven't read any entries, bail. if (length($stamp)) { push @logfile, { stamp => "$stamp", user => "$user", entry => "$entry" }; } else { exit(0); } # Walk the array. If we find a Sent: line, replace the # time/date part of the timestamp with it, and keep the # numeric time in sortable form. If no Sent: line is found, # then use the original timestamp line. my $k; my $dobj; my $str; my $sec; my %permute; for $k (0 .. $#logfile) { $_ = $logfile[$k]{'entry'}; $stamp = $logfile[$k]{'stamp'}; if (/\n\s*Sent:\s+(.*)\n/) { $dobj = ParseDate($1); } elsif (/\n\s*Date:\s+(.*)\n/) { $dobj = ParseDate($1); } else { $dobj = ParseDate($stamp); } if ($dobj) { $logfile[$k]{'stamp'} = UnixDate($dobj, "%a, %d %b %Y %T %z"); $sec = UnixDate($dobj, "%s"); $permute{$sec} = $k; } } # Print the @logfile array in the order determined by %permute. # Strip superfluous trailing newlines from the entry, and remove # leading zeroes from the day of the month. foreach (sort numeric keys %permute) { $k = $permute{$_}; $entry = $logfile[$k]{'entry'}; $entry =~ s/\n\n*$//; $stamp = $logfile[$k]{'stamp'}; $stamp =~ s/, 0/, /; print $stamp, $logfile[$k]{'user'}, "\n$entry\n\n\n"; } exit(0); #--------------------------------------------------------------------- # Numeric sort, debugging. sub dbg { print @_, "\n"; } sub numeric { $a <=> $b; } #--------------------------------------------------------------------- # Print a usage message from the comments and exit. sub usage { my ($emsg) = @_; use Pod::Usage qw(pod2usage); warn "$emsg\n" if defined $emsg; pod2usage(-verbose => 99, -sections => "NAME|SYNOPSIS|OPTIONS"); } sub manpage { use Pod::Man(); my $parser = Pod::Man->new(); open(STDOUT, "| groff -T ascii -man | gcat -s | less") || die "groff\n"; $parser->parse_from_file($0); close STDOUT || die "$myname: can't close stdout: $!\n"; $? = 1 if $? == 255; # from die exit($?); } #--------------------------------------------------------------------- # Print the UUID, current version, or source location. sub myuuid { my $UUID = $1 if q$UUID: 380fe1b4-ba7c-37f3-941e-3cb34d2c27b8 $ =~ /UUID: (.*) /; print "$UUID\n"; exit(0); } sub version { my $VERSION = sprintf("%d.%02d", q$Revision: 1.5 $ =~ /(\d+)\.(\d+)/); my $DATE = $1 if q$Date: 2009/08/03 18:13:40 $ =~ /Date: (.*) /; print "$myname $VERSION $DATE\n"; exit(0); } sub where { my $SOURCE = $1 print "$SOURCE\n"; exit(0); } #--------------------------------------------------------------------- __END__ =head1 NAME sort-logfile - sort LOG file entries by date =head1 SYNOPSIS sort-logfile [-hmuvw] [log ...] =head1 OPTIONS =over 4 =item B<-h> Print a brief help message and exit. =item B<-m> Print the manual page and exit. =item B<-u> Print the script UUID and exit. =item B<-v> Print the version and exit. =item B<-w> Print the source location and exit. =back =head1 DESCRIPTION B will read something that vaguely resembles a LOG-type file and try to sort the entries by date. Intended for use when entering a collection of Outlook-style email messages into a log. =head1 AUTHOR Karl Vogel Oasis Systems, Inc. =cut