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 theTEMP
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.