Tricky has asked for the wisdom of the Perl Monks concerning the following question:

Hi folks,

When I run the following script, the code runs but an unitialised print value is declared. I run it again and the entire file I'm writing to is erased! What am I missing?

#!/usr/bin/perl # addwordspacing3.plx =head1 DESCRIPTION Program will read in an html file, append word spacing attribute to th +e in-line style and print in DOS window. =cut use warnings; use diagnostics; use strict; # Open HTML test file - forward slashes do not need to be escaped. open INFILE, "E:/Documents and Settings/Richard Lamb/My Documents/HTML +/dummy.html" or die "$!: Can't open this file.\n"; while (<INFILE>) { s/(<h[1-6]\s+style=.*)">/$1; word-spacing: 50px">/ig; s/(<li\sstyle=.*)">/$1; word-spacing: 20px">/ig; s/(<p style=.*)">/$1; word-spacing: 20px">/ig; print; } close (INFILE); open (OUTFILE, ">E:/Documents and Settings/Richard Lamb/My Documents/H +TML/dummy.html") or die("$!: Can't write to the HTML file.\n"); print (OUTFILE); close (OUTFILE);

Replies are listed 'Best First'.
Re: Writing to a file: problem
by tcf22 (Priest) on Sep 04, 2003 at 14:30 UTC
    The following code is opening the file for writing(thereby erasing the contents), but really printing nothing to it
    open (OUTFILE, ">E:/Documents and Settings/Richard Lamb/My Documents/H +TML/dummy.html") or die("$!: Can't write to the HTML file.\n"); print (OUTFILE); close (OUTFILE);
    I think this may be what you want. Printing to the outfile in the loop
    open (OUTFILE, ">E:/Documents and Settings/Richard Lamb/My Documents/H +TML/dummy.html") or die("$!: Can't write to the HTML file.\n"); while (<INFILE>) { s/(<h[1-6]\s+style=.*)">/$1; word-spacing: 50px">/ig; s/(<li\sstyle=.*)">/$1; word-spacing: 20px">/ig; s/(<p style=.*)">/$1; word-spacing: 20px">/ig; print OUTFILE $_; } close (OUTFILE);
Re: Writing to a file: problem
by broquaint (Abbot) on Sep 04, 2003 at 14:32 UTC
    Your problem is that you're opening the file for reading, printing out the modified data to STDOUT and then opening it for writing which truncates it. What you probably want is something like this
    my $path = "E:/Documents and Settings/Richard Lamb/My Documents/HTML"; open INFILE, "$path/dummy.html" or die "$!: Can't open this file"; open OUTFILE, ">$path/new_dummy.html" or die "$!: Can't write to the HTML file"; while (<INFILE>) { s/(<h[1-6]\s+style=.*)">/$1; word-spacing: 50px">/ig; s/(<li\sstyle=.*)">/$1; word-spacing: 20px">/ig; s/(<p style=.*)">/$1; word-spacing: 20px">/ig; print OUTFILE $_; } close INFILE; close OUTFILE or die "$0: $!"; rename "$path/new_dummy.html", "$path/dummy.html" or die "$0: $!";
    This way you're writing to the output file as you're modifying the data from the input file (not the input file itself) and once that's finished you replace the input file with the output file.

    See. open, perlopen and rename for more info on the functions used.
    HTH

    _________
    broquaint

Re: Writing to a file: problem
by gjb (Vicar) on Sep 04, 2003 at 14:28 UTC

    In the print (OUTFILE); you just print the empty string to the file you've just read from. So its content will be empty after you close the file.

    You'd better open a temp file to print to and rename it later to the original file's name. File::Temp might help.

    Hope this helps, -gjb-

Re: Writing to a file: problem
by Abigail-II (Bishop) on Sep 04, 2003 at 14:33 UTC
    The line:
    print (OUTFILE);

    prints $_ to the filehandle. But what is $_? It's set by the while loop, so it has the value of the last time the while was checked. Which was at the end of the file, and hence $_ is undefined.

    That's why you get your warning, and that's why the file is empty - undef stringified gives you the empty string.

    Abigail

Re: Writing to a file: problem
by zby (Vicar) on Sep 04, 2003 at 16:03 UTC
    You might consider using the -i switch to the perl interpreter for such editing. Type perldoc perlrun for documentation.