Replacing Strings in Files - Page 3
July 16, 2001
Now that we have a basic handle on creating regular expressions
to match different variations of strings, it's time to introduce
the search and replace operator and write a script to perform a
transformation on a file. The search and replace operator is
placed in front of a set of forward slashes. The difference is
that there is a search expression and a replace expression:
s/search/replace/
Continuing from our set of examples in the previous section,
let's pretend that we need to replace my name as maintainer of
the Web site. Instead, Bob will be filling in for me so we need
to replace all occurrences of Jonathan with Bob. We'll use the
regular expression we built in the last section as the search
string:
s/Jon(ath[ao]n)?/Bob/gi
Notice that we used the g and i
modifiers again. They work the same way in a search and replace
string in that they modify the search part of the operation. Next
we need to write a script that we can run from the command line
that will run the search and replace expression against a file.
1 my $file = $ARGV[0];
2 open (FILE,$file) || die "Cannot read from $file";
3 open (TMP, ">$file.$$") || die "Cannot write to $file.$$\n";
4 my $counter = 0;
5
6 while (<FILE>) {
7 $counter++ if s/Jon(ath[ao]n)?/Bob/gi;
8 print TMP;
9 }
10
11 close FILE,TMP;
12 print "Found Jonathan $counter times\n";
13 rename "$file.$$",$file || die "Cannot update $file\n";
Let's go through the script line-by-line so that we understand
what's happening. In line 1, we're grabbing the filename that was
passed on the command line. If we named the script match.pl and
we wanted to run it against index.html, the command line syntax
would be:
match.pl index.html
On a Unix box, you could either place the location of the Perl
binary at the top of the script or prepend the argument with
Perl, perl match.pl index.html. On Windows, if you have
ActivePerl from ActiveState Corp. installed on your box, it will
know to run the script with the Perl interpreter automatically
based upon the .pl file extension.
In lines 2 and 3, we're opening the file that was passed on the
command line and also opening a temporary file, which will be
used to write a copy of the file with the changes. On line 4, we
initialize the $counter variable that will be used
to count the occurrences of the match for reference. In line 6,
we're using a while statement to loop over each line in
the file, one at a time. Placing the FILE filehandle
inside of the less-than and greater-than characters automatically
reads one line into the $_ variable, which is a
special variable in Perl. This is equivalent to saying:
while ($_ = <FILE>) {
In line 7, we search the $_ string with the search
and replace operator. If a match is found, the match is replaced
with Bob and the $counter variable is incremented by
one. In line 8, we print the line to our temporary file. Again,
we're using the magical $_ variable. By not
specifying a variable, Perl automatically prints $_,
which contains our string read from our file in the while loop.
This is equivalent to saying:
print TMP $_;
In line 11, we close the filehandles for the input and temporary
files. Line 12 reports the number of occurrences of my name that
were found in the file. Finally, line 13 moves the temporary file
to the file that was specified on the command line, replacing the
old file with Jonathan in it with the new file that contains Bob
instead of Jonathan.
Now we have a simple script that can be modified to change
strings in files. By now you should have a handle on the
usefulness and syntax of regular expressions in Perl. You might
even be able to save some time using the script to do search and
replaces on files instead of doing it by hand. But we still
haven't harnessed the power of Perl. We'll do that next.
Regular Expressions Introduced - Page 2
Weaving Magic With Regular Expressions
Replacing Strings in Multiple Files - Page 4
|