
| Linuxtopia Contents |
Perl Tutorial - An Introduction to Perl |
| [an error occurred while processing this directive] |
Contents5. Taste of PerlQuite useful Perl programs can be short. Suppose we want to change the same text in many files. Instead of editing each possible file or constructing some cryptic find, awk, or sed commands, you could issue a single command: Example: Amazing Perl One-Liner That Substitutes Text In Multiple Files perl -e 's/gopher/World Wide Web/gi' -p -i.bak *.html This command, issued at the Unix prompt, executes the short Perl program specified in single quotes. This program consists of one perl operation; it substitutes for original word "gopher" the phrase "World Wide Web", (globally, ignoring case). The re mainder of the Unix command indicates that the perl program should run for each file ending in ".html" in the current directory. If any file "blah.html" needs changing, a backup of the original is made as file "blah.html.bak". Programming Perl lists additional handy one-liners. For those accustomed to "classic" procedural programming, the "amazing one-liner" above can be expanded in Perl in a style more like C or Pascal: Example: Global Substitution, The Scenic Route #!/usr/local/bin/perl -w
# File: go2www
# This Perl program in classic programming style changes
# the string "gopher" to "World Wide Web" in all files
# specified on the command line.
# 19950926 gkj
$original='gopher';
$replacement="World Wide Web";
$nchanges = 0;
# The input record separator is defined by Perl global
# variable $/. It can be anything, including multiple
# characters. Normally it is "\n", newline. Here, we
# say there is no record separator, so the whole file
# is read as one long record, newlines included.
undef $/;
# Suppose this program was invoked with the command
# go2www ax.html big.basket.html candle.html
# Then builtin list @ARGV would contain three elments
# ('ax.html', 'big.basket.html', 'candle.html')
# These could be accessed as $ARGV[0] $ARGV[1] $ARGV[2]
foreach $file (@ARGV) {
if (! open(INPUT,"<$file") ) {
print STDERR "Can't open input file $bakfile\n";
next;
}
# Read input file as one long record.
$data=<INPUT>;
close INPUT;
if ($data =~ s/$original/$replacement/gi) {
$bakfile = "$file.bak";
# Abort if can't backup original or output.
if (! rename($file,$bakfile)) {
die "Can't rename $file $!";
}
if (! open(OUTPUT,">$file") ) {
die "Can't open output file $file\n";
}
print OUTPUT $data;
close OUTPUT;
print STDERR "$file changed\n";
$nchanges++;
}
else { print STDERR "$file not changed\n"; }
}
print STDERR "$nchanges files changed.\n";
exit(0);
Questions:
The Perl Creed is, "There is more than one way!" This noble freedom of expression however results in the first of the four Perl Paradoxes: Perl programs are easy to write but not always easy to read. For example, the following lines are equivalent! if ($x == 0) {$y = 10;} else {$y = 20;}
$y = $x==0 ? 10 : 20;
$y = 20; $y = 10 if $x==0;
unless ($x == 0) {$y=20} else {$y=10}
if ($x) {$y=20} else {$y=10}
$y = (10,20)[$x != 0];
|