I’m teaching myself Perl and Regex by reading Jeffrey Friedl’s excellent Mastering Regular Expressions.
While trying to solve the “A Small Mail Utility” exercise starting on page 53 I stumbled upon the problem of not knowing how to save the content of file into a variable starting from an offset.
So here’s my (shortened) script.
my ($body, $line, $subject);
$body = $line = $subject = "";
open(MYFILE, "king.in") || die("Could not open file!");
# Read the file's content line by line
while ($line = <MYFILE>)
{
# An empty line marks the beginning of the body
if ($line =~ m/^\s+$/ ) {
# HERE IS THE ISSUE
# Save the file content starting from the current line
# to the end of the file into $body
last;
}
if ($line =~ m/^subject: (.*)/i) {
$subject = $1;
}
# Parse additional data from the mail header
}
close(MYFILE);
print "Subject: Re: $subject\n";
print "\n" ;
print $body;
I did some online research but couldn’t figure out how to put the remainder of the file (i.e., the email body) into the variable $body.
I figured out that I could get the current position within the file in bytes using $pos = tell(MYFILE);
Eventually I ended up with the working but unsatisfactory solution of putting the file’s lines first into an array.
How do I save the file content starting from an offset (either as a line number or bytes) into $body?
Edit:
My solution -as provided by vstm- is to use $body = join("", <MYFILE>) to read in the rest of the file when encountering the empty line that marks the beginning of the body.
The whole script I wrote can be found here.
Although this works great for me now, I would still like to know how to say (elegantly) in Perl “give me lines x to z of this file”.
Thanks for your advice everybody.
Instead of stopping immediately, you could just set a flag that says “now I’m reading the body”. Like that:
It’s like a mini state-machine. First It’s in the “header”-state and if the first empty newline is read it switches to the “body”-state and just appends the body to the variable.
Alternatively you could just slurp the rest of the
MYFILE-handle into the body at the end of your originalwhile-loop and before theclose: