Writing a Filter
Problem
You want to write a program that takes
a list of filenames on the command line and reads from STDIN if no
filenames were given. You’d like the user to be able to give
the file "-" to indicate STDIN or
"someprogram
|" to indicate the
output of another program. You might want your program to modify the
files in place or to produce output based on its input.
Solution
Read lines with <>:
while (<>) {
# do something with the line
}Discussion
When you say:
while (<>) {
# ...
}Perl translates this into:[13]
unshift(@ARGV, '-') unless @ARGV;
while ($ARGV = shift @ARGV) {
unless (open(ARGV, $ARGV)) {
warn "Can't open $ARGV: $!\n";
next;
}
while (defined($_ = <ARGV>)) {
# ...
}
}You can access ARGV and $ARGV
inside the loop to read more from the filehandle or to find the
filename currently being processed. Let’s look at how this
works.
Behavior
If the user supplies no arguments, Perl sets @ARGV
to a single string, "-". This is shorthand for
STDIN when opened for reading and STDOUT when opened for writing.
It’s also what lets the user of your program specify
"-" as a filename on the command line to read from
STDIN.
Next, the file processing loop removes one argument at a time from
@ARGV and copies the filename into the global
variable $ARGV. If the file cannot be opened, Perl
goes on to the next one. Otherwise, it processes a line at a time.
When the file runs out, the loop goes back and opens the next one,
repeating the process until @ARGV is exhausted.
The open
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access