There have been good solutions while'ing through the file and updating a variable on a match. This is the most simple (and due to this - best) solution for smaller logfiles.
Here is my solution for bigger logfiles:
sysopen logfile,'/tmp/file.log',O_RDONLY; # Open file
my $ReadLen = 1024; # Inital block to read
my $N1; # Storage for number #1
my $N2; # Storage for number #2
while (! (defined($N1) and defined($N1)) {
my $Buffer;
sysseek logfile,($ReadLen * -1),2
sysread logfile,$Buffer,$ReadLen;
$Buffer =~ /processed\=\'destination\(df\_suu\=(\d+).*?$/s and $N1 =
+$1;
$Buffer =~ /processed\=\'destination\(d_mysql_suu\=(\d+).*?$/s and $N
+2 = $1;
$ReadLen += 1024;
}
close logfile;
print "df_suu=$N1\nd_mysql_suu=$N2\n";
This code opens the logfile, prepares space for the two values ($N1 and $N2) and starts reading the file: If defines a buffer, seeks (goes to position inside the file) to $ReadLen bytes before the end of the file and reads the last $ReadLen bytes into $Buffer. Every read reads 1024 bytes more than the previous.
The two regexp-lines match the numbers you need, but the .*$ at the end means that the match should be as near to the end of the buffer as possible (.* matches 0-or-more of all chars which usually makes Perl to match as many as possible, but the ? after the * says: Match as few bytes as possible).
When both regexp's matched, the loop is broken and both values are printed. Otherwise the number of bytes which should be read is increased and the process starts from the beginning.
This solution reads only 1k and plus 1k for each additional try from the logfile. This is much faster than reading a logfile which may be 2 GB or more.
Notice:
ALWAYS use sys(open|read|seek) or never use them (for the same filehandle). Mixing up a traditional open with sysseek and a while (<filehandle>) will not do what you want! (rtfm (perlfunc) for more information)
Another option would be reading everything in 1k-blocks, but remember: Your read may get half a line and the next could get the other half. This may lead to a non-match on both half's, so you need to take care that you include everything from the beginning previous read-block until the first \n and ignore this at the match before. Imagine your 1k-limit would be at ||: df_suu=12||34567...
You may need to use Fcntl; for sysopen and sysseek's constants
(This code is untested, there may be typos or other problems.)