Ok, the following assumes that the file is already sorted by invoice number and then timestamp.
#!/usr/bin/perl
use warnings;
use strict;
#our $Logfile = 'file.log';
#open my $fh, $Logfile or die "Can't open $Logfile: $!\n";
my $fh = \*DATA; # Testing purposes
# The first element of @records is the "current" line.
# The second element is the "next" line, if any.
my @records = get_next_record($fh);
do {
# Read the next line
push @records, get_next_record($fh);
if(
($records[0]{name} eq 'Larry' or $records[0]{name} eq 'Robb')
and not
(
# No more lines
$#records
and
# Not the name
($records[1]{name} eq 'Larry' or $records[1]{name} eq 'Robb')
)
) {
print $records[0]{record};
# Skip to the next set of records, and start over.
# ('skip' is removed immediately and is only for place-holding.)
@records = ('skip', find_next_record_set($fh, $records[0]{inv}));
}
# Remove the old "current" line, and make the next line current.
shift @records;
} while @records;
exit;
sub parse_record {
my $record = shift;
my %data = ('record' => $record);
@data{qw(inv name date time)} = split(/\s+/, $record);
return \%data;
}
sub get_next_record {
my $fh = shift;
my $rec = <$fh>;
return defined($rec) ? parse_record($rec) : ();
}
sub find_next_record_set {
my $fh = shift;
my $rs = shift;
my $line;
1 while(defined($line = <$fh>) and $line =~ /^\Q$rs/);
return defined($line) ? parse_record($line) : ();
}
__DATA__
1056128833340 Robb 2003-06-20 665 **
1056128833340 t028348 2003-06-20 607
1055439973653 T012697 2003-07-22 962
1055439973653 t012697 2003-07-22 948
1055439973653 t806174 2003-07-15 792
1055439973653 T806174 2003-07-15 791
1055439973653 t021191 2003-07-08 786
1055439973653 Robb 2003-06-17 503
1055439973653 Larry 2003-06-16 815 **
1055439973653 t021191 2003-06-12 646
bbfu
Black flowers blossom
Fearless on my breath |