home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  

12.2 Globbing

The command prompt usually takes a solitary asterisk ( * ) command-line argument and turns it into a list of all of the filenames in the current directory. So, when you say del * , you'll remove all of the files from the current directory. (Don't try this unless you like restoring the current directory from your backup device.) Similarly, *.c as a command-line argument turns into a list of all filenames in the current directory that end in .c , and c:\temp\backup* is a list of all filenames in the directory c:\temp that begin with backup . (If this information is new to you, you probably want to read some more about using the command line somewhere else before proceeding.)

The expansion of arguments like * or *.c into the list of matching filenames is called globbing . Perl supports globbing through a very simple mechanism - just put the globbing pattern between angle brackets or use the more mnemonically named glob function, like this:

@a = <*.plx>;
@a = glob("*.plx");

In a list context, as demonstrated here, the glob returns a list of all names that match the pattern or an empty list if none match. In a scalar context, the next name that matches is returned, or undef is returned if there are no more matches; this process is very similar to reading from a filehandle. For example, to look at one name at a time:

while (defined($nextname = <c:/scripts/*.plx>)) {
        print "one of the files is $nextname\n";

Here the returned filenames begin with c:\scripts\ , so that if you want just the last part of the name, you'll have to whittle it down yourself, like so:

while ($nextname = <c:/scripts/*.plx>) {
    $nextname =~ 

s#.*/##; # remove part before last slash
    print "one of the files is $nextname\n";

Multiple patterns are permitted inside the file glob argument; the lists are constructed separately and then concatenated as if they were one big list:

@fred_barney_files = <fred* barney*>;

In other words, the glob returns the same values that an equivalent dir /B command with the same parameters would return.

Although file globbing and regular-expression matching function similarly, the meanings of their various special characters are quite different. Don't confuse the two, or you'll be wondering why <\.c$> doesn't find all of the files that end in .c !

The argument to glob is variable interpolated before expansion. You can use Perl variables to select a wildcard based on a string computed at runtime:

if (-d "c:/tmp") {
        $where = "c:/tmp";
} else {
        $where = "c:/temp";
@files = <$where/*>;

Here we set $where to be one of two different directory names, based on whether or not the directory c:\tmp exists.[ 3 ] We then get a list of files in the selected directory. Note that the $where variable is expanded, which means the wildcard to be globbed is either c:\tmp\* or c:\temp\* .

[3] If we were really trying to find where the temporary directory was, we'd be checking the ENV hash for the TEMP variable:

my $tmp = $ENV{'TEMP'} || $ENV{'TMP'};

There's one exception to this rule: the pattern <$var> (meaning to use the variable $var as the entire glob expression) must be written as <${var}> for reasons we'd rather not get into at this point.[ 4 ]

[4] The construct <$fred> reads a line from the filehandle named by the contents of the scalar variable $fred . Together with some other features not covered in this book, this construct enables you to use i ndirect filehandles in which the name of a handle is passed around and manipulated as if it were data.