my $MAXBUFLEN = 1024 * 1024; # 1M sub sort_logfile { my $file = shift; my @off = (0); my @lines; open(INFILE, "<$file"); while() { push @off, tell; if (/^\d.*?\[([^\]]+)\]/) { push @lines, [$1, $.-1]; } else { # assume any non-matching line # is a continuation of the previous $off[-2] = $off[-1]; next; } } @lines = sort { $a->[0] cmp $b->[0] } @lines; open(INFILE,"<$file"); my $line = 0; my $buf; while (my $i = shift @lines) { my ($start, $end) = ($i->[1],$i->[1]+1); while( @lines and $lines[0]->[1] == $end) { shift @lines; $end++; } ($start,$end) = @off[$start,$end]; my $len = $end - $start; while ($len > 0) { seek(INFILE, $start, 0) or die "seek: $!"; read(INFILE, $buf='', $len > $MAXBUFLEN ? $MAXBUFLEN : $len) or die "read: $!"; print $buf; $len -= length $buf; } } }