 |
Pipes and Command Line Variables in Perl
|
This tutorial walks through
handling pipes and command line variables in a Perl script.
Automatic File Looping
In Unix, files can be “piped” to programs. Programs also can accept
filenames on the command line. For example, you can use the “more” command
the following ways:
more fandango.text
cat fandango.text | more
If your program expects files as input, you can easily make it work with both
command line filenames and files piped to it.
while (<>) {
print;
}
This is an example of a Perl program that makes assumptions. It is the equivalent
of:
while (<>) {
print $_;
}
The built-in variable “$_” is the current line of whatever it
is we’re looking at through the loop. We’ll talk about the <> construction
later. Basically, it opens up every file in the array @ARGV or whatever was
piped to the program if there is no array @ARGV.
Let’s say you want to search
through the files for some text:
$SearchText = shift(@ARGV);
while (<>) {
if (/$SearchText/) {
print;
}
}
There are a few new items in there.
The “shift” function takes
the first item out of an array and returns it to the scalar variable on the
left of the equation. It removes that item completely from the array. So, if
@ARGV had five items before this, it now has only four.
The comparison “/$SearchText/” is like “eq” except
that it looks for the text anywhere inside the current line. This is a regular
expression, and we’ll talk more about that in a later chapter. One other
important option is case insensitivty:
$SearchText = shift(@ARGV);
while (<>) {
if (/$SearchText/i) {
print;
}
}
Adding “i” after the last “/” tells
Perl to ignore case when making this comparison.
Command Line Variables
You have an array that consists of the command line, called @ARGV. If you want
to know how many items are in this array, use the scalar variable $#ARGV.
To access a scalar in that array, use $ARGV[$number], where ‘$number’ is
the number of the word or phrase on the command line that you want, zero
being the first.
foreach $Counter (0..$#ARGV) {
print "Command line argument $Counter is $ARGV[$Counter]\n";
}
This will print out each command line argument and its index number.
Pipes
There is a third type of variable in Perl called a ‘filehandle’.
You’ve seen one filehandle already: <> is a ‘handle’ to
either all of the files on the command line, or the ‘standard input’ if
there are no arguments on the command line. You could also write <ARGV> instead
of <>. This is a filehandle to all of the scalars in @ARGV (and in Unix,
is equivalent to <>). It’s a special construction; normally, it
wouldn’t work that way.
If you want your program to accept
both standard input (what gets ‘piped’ via
the Unix ‘|’ operator) and have command line arguments, you can
use the filehandle <STDIN> to receive the piped information.
foreach $ARG (@ARGV) {
if ($ARG eq "upper") {
$doUpper = 1;
} elsif ($ARG eq "lower") {
$doLower = 1;
} elsif ($ARG eq "reverse") {
$doReverse = 1;
}
}
while (<STDIN>) {
chomp;
$Result = $_;
$Result = uc($Result) if $doUpper;
$Result = lc($Result) if $doLower;
$Result = reverse($Result) if $doReverse;
print "$Result\n";
}
A couple of new things here. You
can try it out and see: whatever you pipe to this script gets reprinted,
possibly with each line reversed, converted
to upper case or converted to lower case. The ‘foreach’ loop goes
through each command line option and checks if it equals one of our munge operators.
The ‘while’ loop stops when <STDIN> runs out of data.
The ‘chomp’ function removes the last character of the variable
$_ if the last character is a carriage return. And $_, if you recall, is the
current line of whatever ‘file’ we happen to be working on.
This is a new version of the ‘if’ statement as well. Each ‘$Result’ line
is executed only if the appropriate variable is set.
About
this Tutorial
This tutorial is written by Jerry Stratton and is published
under the GNU Free Documentation License.
|