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

I've read several nodes concerning a similar problem, but I haven't had enough experience with Perl to know how to modify the nodes to work for me. I thought I had it, but I'm not quite there. So, here's my question.

I'm trying to open an html file, find a string, and replace the string.

Here's what I've got.
open(FH, "file.html"); while(<FH>) { chomp; my $string = "$_"; my $find = "here.company.com/pagedir"; my $replace = "there.company.com/"; $find = quotemeta $find; $string =~ s/$find/$replace/g; print $string; } close(FH);
This works well to dump the output to the screen, but it doesn't replace the string in the file.

Thanks for your help.

Replies are listed 'Best First'.
Re: Read from a file and replace
by runrig (Abbot) on Aug 17, 2001 at 23:10 UTC
    See perldoc perlrun and the -i operator (along with -p and -n (-p in your case)).
    perl -pi.bak -e 's#\Qhere.company.com/pagedir#there.company.com/#g' fi +le1 file2 etc...
    Otherwise you are going to have to open a new output file, print to it, then rename the new file to the old file name, which is what the -i switch implicitly does.
Re: Read from a file and replace
by bjelli (Pilgrim) on Aug 18, 2001 at 00:18 UTC
    What you want is called "inplace editing" in perl. Here it is, try to spot the difference to your own code:
    $^I = ".bak"; @ARGV = ('file.html'); while(<>) { # chomp; # don't want to loose the linebreaks my $string = "$_"; my $find = "www.3sat.de/boerse/boerse_service.html"; my $replace = "there.company.com/"; $find = quotemeta $find; $string =~ s/$find/$replace/g; print $string; }

    Here's what you do:

    1. Put the list of files you want to treat into @ARGV
    2. Set $^I. For every file treated, the original is saved with $^I added to the filename
    3. read from <>
    4. print to STDOUT

    Perl does all the right things: it opens the files in @ARGV one by one, creates backups, and writes your output back into the original files.

    P.S. Everything has already been discussed on perlmonks: see modifying and overwriting a file

    --
    Brigitte    'I never met a chocolate I didnt like'    Jellinek
    http://www.horus.com/~bjelli/         http://perlwelt.horus.at
Re: Read from a file and replace
by chiller (Scribe) on Aug 17, 2001 at 23:14 UTC
    You are just opening a file for reading instead of writing.

    try something like this (there are a zillion ways to do it):

    open (FH, "file.html"); my $find = quotemeta('here.company.com/pagedir'); ## you can use quotemeta like this. my $replace = 'there.company.com'; ## also it is better to define these outside of your loop my $outstring; ## this is a temp variable while (<FH>) { my $string = $_; $string =~ s/$find/$replace/g; $outstring .= $string; ## this concatenates $string to $outstring } close (FH); open (FH, ">file.html"); ## > means open new file for writing print FH $outstring; ## a plain 'print' prints to STDOUT. you want to print to ## your filehandle instead. close (FH);
    you _may_ want to change the line above to:open(FH, ">file.html.bak"); or something just for safety purposes.

    umm, yes. i hope this explains things. no one yell at me if this is too obtuse.

    chiller

Re: Read from a file and replace
by Sifmole (Chaplain) on Aug 17, 2001 at 23:18 UTC
    You are changing the copy of the line in your program and then printing it to STDOUT (the screen). You would need to open a file for writing and write the lines you read in, and the ones you change to that new file.

    Added code, and made some changes... The new file will be in newfile.html.

    open(FH, "<file.html"); open(OUT, ">newfile.html"); my $line = ''; my $find = quotemeta("here.company.com/pagedir"); my $replace = "there.company.com/"; while($line = <FH>) { $string =~ s/$find/$replace/g; print OUT $string; } close(FH); close(OUT);
    runrig's will work as well, and it significantly shorter.
Re: Read from a file and replace
by Rudif (Hermit) on Aug 18, 2001 at 03:12 UTC
    And there is the Slurp module - saves you a couple of lines
    #!perl -w use strict; use File::Slurp; my $find = quotemeta("here.company.com/pagedir"); my $replace = "there.company.com/"; my @lines = read_file "file.html"; foreach (@lines) { s/$find/$replace/g; } write_file "newfile.html", @lines;
    Rudif
Re: Read from a file and replace
by toddler (Initiate) on Aug 17, 2001 at 23:38 UTC
    Thanks all. I got it with your help. Gotta get back to learnin this Perl stuff.