Writing a Filter


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.


Read lines with <>:

while (<>) {
    # do something with the line


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";
    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.


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

Get Perl Cookbook now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.