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

Hi, I am, at the moment, braindead. I have a little script that goes through a text file, finds a line w/ a string, then copies the entire line w/ the replaced string to another text file. But now I need to just *replace* the string, and I am definitely missing something:
use strict; open (FILE ,"c:/index.htm"); for my $line (<FILE>) { if ($line =~ /foo/) { $line =~ s/foo/bar/gms; print FILE "$line"; #obviously doesn't work print $line; } } close FILE;
the finding works fine, adn the replacing works fine *in memory*, but how do I replace the entire line (or just the string, same thing) in the original file? Many thanks, -John

Replies are listed 'Best First'.
Re: find and replace
by JediWizard (Deacon) on Jun 21, 2005 at 15:05 UTC

    try:

    perl -pi -e 's/foo/bar/gms' File.txt

    And see perlrun, to understand the flags -p, -i, and -e


    They say that time changes things, but you actually have to change them yourself.

    —Andy Warhol

Re: find and replace
by goober99 (Scribe) on Jun 21, 2005 at 15:09 UTC
    A simple way to do this would be to use Tie::File. It is one of the core modules in the Perl distribution, so you would not have to install anything extra. Here is a snippet from a script I wrote using Tie::File:
    tie @ThisFile, 'Tie::File', 'c:/index.html'; foreach(@ThisFile) {s/$SearchText/$ReplaceText/g}; untie @ThisFile;
      thanks, this works great.
Re: find and replace
by ambrus (Abbot) on Jun 21, 2005 at 15:17 UTC

    Either you want inplace edit with the $^I variable; or write the results to a temporary file created with File::Temp::tempfile and then rename the new file to the original one.

    Here's an example for the second one:

    use warnings; use strict; use File::Temp "tempfile"; my $i = "yourfile.txt"; # filename my ($O, $o) = tempfile; open my $I, $i or die "open: $!"; while (<$I>) { s/foo/bar/g; print $O $_; } close $O or die; rename $o, $i; __END__
Re: find and replace
by tlm (Prior) on Jun 21, 2005 at 15:53 UTC

    Just for completeness, here's an example of one of the approaches that ambrus already mentioned:

    { local $^I = ''; local @ARGV = 'c:/index.htm'; while ( <> ) { s/foo/bar/g; print; } }
    I think that Tie::File rocks, but it's more firepower than the problem requires, I think.

    Also, why the /m in your s///, when there is no ^ or $ in the regex? Likewise, why the /s when there is no . in the regex?

    the lowliest monk

Re: find and replace
by GrandFather (Saint) on Jun 21, 2005 at 20:43 UTC
    As an aside, if you are editing HTML be very very carefull. You should investigate the various HTML::... modules available on CPAN.

    Perl is Huffman encoded by design.