Let's dive in with a small program which changes patterns in text files. This has lots of applications, for example changing variable names across code files. It also provides a template for other file processing programs.
#! /usr/bin/perl -w use strict; { my ($file, $line, $contents); # process files foreach $file (@ARGV) { if (-f $file) { print("processing $file\n"); # read file contents open(FILE, $file) or die("can't open $file for read"); $contents = ''; while ($line = <FILE>) { $contents .= $line; } close(FILE) or die("can't close $file after read"); # change patterns throughout $contents =~ s/pattern1/pattern2/g; $contents =~ s/pattern3/pattern4/g; # write out edited file contents open(FILE, ">$file") or die("can't open $file for write"); print(FILE $contents); close(FILE) or die("can't open $file for write"); } } }
This covers quite a bit of Perl ground:
#! /usr/bin/perl -wFirst the #! line identifying the interpreter the shell will call to run the program. If this doesn't resolve to a valid interpreter the shell will complain. The program must have execute permission. The -w flag enables warnings and should always be used.
use strict;This invokes the strict pragmatic module, which among other things insists that all variables be declared.
my ($file, $line, $contents);A 'my' variable declaration, local to enclosing braces. Perl variable names start with special characters, discussed below.
# process files foreach $file (@ARGV) {One of Perl's looping statements. @ARGV is a system array which contains the program command line arguments; the string variable $file is assigned each argument in turn and the loop body is executed. Perl comments start with # and run to the end of the line.
if (-f $file) {Tests if the file is editable. If it is a directory the test will fail. Perl provides many different file tests.
print("processing $file\n");A C-style call of a Perl function; both shell and programming language syntaxes can be used. The double-quoted string features variable and backslash interpolation, one of Perl's syntactic strengths.
# read file contents open(FILE, $file) or die("can't open $file for read"); $contents = ''; while ($line = <FILE>) { $contents .= $line; } close(FILE) or die("can't close $file after read");The file is opened and the contents are read into a single string, which could be megabytes in size if required.
# change patterns throughout $contents =~ s/pattern1/pattern2/g; $contents =~ s/pattern3/pattern4/g;Perl's regular expression magic at work, changing all instances of one pattern to another in the string. You could add more lines like this, to change many patterns.
# write out edited file contents open(FILE, ">$file") or die("can't open $file for write"); print(FILE $contents); close(FILE) or die("can't open $file for write");Finally the file is re-opened, this time for writing, and the modified contents are written out.