Exercise: The Unix grep

Previous Table of Contents Next

Exercise: The Unix grep

As you get further along in this book, the exercises will present you with more and more useful tools. This exercise presents a stripped-down version of the Unix grep utility. The Unix grepnot to be confused with Perl's grep function, introduced in Hour 6, "Pattern Matching"searches files for patterns. This exercise presents a utility that will prompt for a directory name and a pattern. Every file in that directory will be searched for that pattern, and lines matching that pattern will be printed.

In future exercises, this utility will be modified to search subdirectories (see Hour 15, "Finding Permanence") and to take command-line arguments (see Hour 12, "Using Perl's Command-Line Tools"). Stay tuned for details.

Using your text editor, type the program from Listing 10.1 and save it as mygrep. If possible, be sure to make the program executable according to the instructions you learned in Hour 1, "Getting Started with Perl." Also, make sure that you don't rename this file to grep on a Unix system because it could be mistaken for the real grep utility.

When you're all done, try running the program by typing the following at a command line:

perl -w mygrep

or, if your system enables you to make the file executable,


Listing 10.1. Complete Listing for mygrep

1:   #!/usr/bin/perl -w


3:   use strict;


5:   print "Directory to search: ";

6:   my $dir=<STDIN>; chomp $dir;

7:   print "Pattern to look for: ";

8:   my $pat=<STDIN>; chomp $pat;


10:   my($file);


12:   opendir(DH, $dir) || die "Cannot open $dir: $!";

13:   while ($file=readdir DH) {

14:       next if (-d "$dir/$file");

15:       if (! open(F, "$dir/$file") ) {

16:           warn "Cannot search $file: $!";

17:           next;

18:       }

19:       while(<F>) {

20:           if (/$pat/) {

21:               print "$file: $_";

22:           }

23:       }

24:       close(F);

25:   }

26:   closedir(DH);

Line 1: This line contains the path to the interpreter (you can change it so that it's appropriate to your system) and the w switch. Always have warnings enabled!

Line 3: The use strict directive means that all variables must be declared with my and that bare words must be quoted.

Lines 58: $dir, the directory to be searched, and $pat, the pattern to search for, are retrieved from STDIN. The newlines at the end of each are removed.

Line 10: $file is declared as private to satisfy use strict. $file is used later in this program.

Line 12: The directory $dir is opened; an error message is printed if this operation fails.

Line 13: The entries are retrieved from the directory one at a time and stored in $file.

Line 14: Any directory entry that's really a directory itself (-d )is rejected. Notice that the pathname checked is $dir/$file. This path must be checked because $file doesn't necessarily exist in the current directory; it exists in $dir. So the full pathname to the file is $dir/$file.

Lines 1518: The file is opened, again using the full pathname $dir/$file, and rejected if it does not open.

Lines 1923: The file is searched, line by line, for a line that contains $pat. A matching line is printed.

Listing 10.2 shows a sample of the mygrep program's output.

Listing 10.2. Output from mygrep

Directory to search: /home/clintp

Pattern to look for: printer

mailbox: lot of luck re-inking Epson printer ribbons with # the following allows the user to pick a printer for

    Previous Table of Contents Next
    © 2000- NIV