LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   How do I Find and Replace text within files using Perl (no one-liners please) (https://www.linuxquestions.org/questions/programming-9/how-do-i-find-and-replace-text-within-files-using-perl-no-one-liners-please-778948/)

GuerillaSquad 12-30-2009 03:10 PM

How do I Find and Replace text within files using Perl (no one-liners please)
 
Hi,

I have a Perl script I am trying to write. In all the examples I see of filehandle the infile and outfile are different. ARGV[0] and [1] for example.

I am currently running a File::Find in my script and when I call the find method I want it to be able to open a found file, search the file for "cat", replace it with "dog", close the file.

I have two questions:
1. Do I have to OPEN the file for READ, close it and then OPEN it for WRITE in two seperate statements?

2. How do I do the following: ?

------------
For example:
------------
Filename is foo
* foo currently has "mike" and "bob" in it for contents.

If I open the file like this >>Larry,
I will get "mike" "bob" "larry"

If I open the file like this >Larry
I will get "larry"

What I want is to replace "bob" with "larry"
I would get "mike" "larry"

I plan to use s/bob/larry/g to do the work but how do I open the file without deleting content?

Thank you,

SethsdadtheLinuxer 12-30-2009 04:52 PM

#1 is yes. Perl can only handle the file in one mode at a time. here's an easy way to do it
(hope the indentation isn't crappy)
use File::Copy;
my $filein = $ARGV[0];
my $filetmp = $filein.'_'.$$;
open (my $fh_in, "<", $filein) or die;
open (my $fh_out, ">$filetmp") or die;
while (<$fh_in>) {
my $x = $_;
$x =~ s/bob/joe/g;
print $fh_out $x;
}
close ($filein);
close ($filetmp);
move $filetmp $filein;
exit;

Telemachos 12-30-2009 08:34 PM

Sethsdad's method works very well, and it's such a common desire that there's a built-in way that simplifies things a bit.

If you set the $^I default variable and use the <> operator, you can edit the file in place and get a backup for free. Behind the scenes, Perl takes care of duping the file safely and making the backup for you:

Code:

# Set the suffix for backups to '.bak' and turn on in-place editing
$^I = '.bak'

while (<>) {
    s/bob/larry/g;
}

That's it. The only trick is that when you run this, Perl will perform the substitution on whatever files you specify on the command line. So if the file you want to edit is data.txt, save this script as editor and then you call it as perl editor data.txt.

GuerillaSquad 12-31-2009 09:01 AM

Hi there. Thanks for the help.


All times are GMT -5. The time now is 10:24 AM.