Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

search-and-replace in files

by vxp (Pilgrim)
on May 20, 2003 at 20:03 UTC ( #259561=perlquestion: print w/replies, xml ) Need Help??

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

sorta stupid because a lot of tools out there implement this.. i wanted to write my own just out of boredom i suppose. give the script a directory, what string to search in files for, and what string to replace it with.. and off it goes however.. it does all this, except make any changes to the files. heh. was wondering what blatantly obvious thing i forgot (sometimes its the most obvious that escapes people) can you find it? :)
#!/usr/bin/perl use Getopt::Std; getopt("d:s:r:"); print "dir: $opt_d search for: $opt_s replace with: $opt_r\n"; print "Is the above info correct? y/n: "; $confirmation = <>; if ($confirmation =~ /y/i) { opendir(DIR, $opt_d) or die "Couldn't opendir $opt_d\n"; while (defined($file = readdir(DIR))) { next if $file =~ /^\.\.?$/; # skip . and .. open(FILE, "$opt_d/$file") or die "Couldn't open $file +: $!\n"; while (defined($line = <FILE>)) { chomp $line; if ($line =~ /$opt_s/) { $line =~ s/$opt_s/$opt_r/; print "changed $opt_s to $opt_r in $fi +le\n"; } } close(FILE); } closedir(DIR); }

Replies are listed 'Best First'.
Re: search-and-replace in files
by tune (Curate) on May 20, 2003 at 20:12 UTC
    You are changing the file only in memory :-)

    Write all the lines including changed ones into a variable, and then when you're done with reading the file, open it again for writing. Then write the content of your variable into it.

    --
    tune

Re: search-and-replace in files
by Enlil (Parson) on May 20, 2003 at 20:15 UTC
    You change the value of $line, then you print out that it happened. But you never actually make any changes to the file (i.e. changing the value of $line does not change that line in the file, you have to write it back out).

    BTW you might want to take a look at File::Find, and maybe $^I in perlvar (or the -i switch).

    -enlil

(z) Re: search-and-replace in files
by zigdon (Deacon) on May 20, 2003 at 20:17 UTC
    Isn't this very similar to this?
    perl -i.bak -pe ' BEGIN {chdir shift}; s/original regex/new/; ' /path/to/dir file1 file2 file3 file4 ...

    -- zigdon

Re: search-and-replace in files
by freddo411 (Chaplain) on May 20, 2003 at 21:27 UTC
    Here's a simple version that requires you to edit the script for each new find and replace...

    #! /usr/local/bin/perl5 $search_for = 'foo'; $replace_with = 'bar'; foreach $filename (@ARGV) { open(FILE, "$filename"); @data = <FILE>; close(FILE); for($i = 0; $i < @data; $i++){ @data[$i] =~ s/$search_for/$replace_with/g; } open(FILE, ">$filename"); print FILE (@data); close(FILE); }
Re: search-and-replace in files
by wufnik (Friar) on May 21, 2003 at 14:13 UTC
    aloha. bit late but i should not miss this opportunity to advertise ken williams' totally insane Tie::Text module;

    here goes: following file = masssub.pl

    use Tie::TextDir; ($old, $new, $dir) = @ARGV; tie %dirs, 'Tie::TextDir', ($dir || "."), 'rw'; map { $dirs{$_} =~ s/$old/$new/g } keys %dirs; untie %dirs;
    invoke via massub.pl subthis forthis inthisdirectory

    careful to specify the dir or it will sub in the working one.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://259561]
Approved by jonnyfolk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2022-05-21 10:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (76 votes). Check out past polls.

    Notices?