Filehandles, files, directories
glob#
Expand a shell-style filename pattern into the list of matching paths.
glob takes a pattern string such as "*.c" or "src/**/*.pm" and
returns the filenames on disk that match, in the same style a Unix
shell would produce. In list context it returns every match at once;
in scalar context it acts as a stateful iterator, returning one match
per call and undef when the list is exhausted. With no
argument, glob expands the pattern in $_.
Synopsis#
glob EXPR
glob
<PATTERN>
What you get back#
In list context, a (possibly empty) list of filenames. An empty list
means the pattern did not match — it is not an error and does not
set $!.
In scalar context, glob is an iterator: each call returns the next
match, and after the last match one more call returns undef.
The iterator state is per-call-site, so two while (my $f = glob ...)
loops at different source locations do not interfere.
my @mp3 = glob "*.mp3"; # list context
while (my $f = glob "*.mp3") { } # scalar context, iterator
Global state it touches#
$_— read whenglobis called with no argument.globitself does not set$!on “no matches”. A non-match is a legitimate empty list, not a failure.When a
globexpression is used as the condition of awhileorforloop, Perl implicitly assigns the result to$_and tests for definedness, not truth — so a filename of"0"still keeps the loop running.
The <...> shortcut and how Perl picks it#
<*.c> is an alternative syntax for glob("*.c"). The angle-bracket
form shares a reader with <FH> (readline); the parser
decides which one you meant at compile time based on what sits
between the angle brackets:
Bareword that could be a filehandle (
<STDIN>,<FH>) →readline.A simple scalar (
<$fh>) →readlineon that handle.Anything that looks like a pattern (
<*.c>,<"*.txt">,<${dir}/*>) →glob.
The named function glob is unambiguous and more searchable. Prefer
it in new code; reach for <...> only for the shortest throwaway
patterns.
my @txt = <"*.txt">; # same as glob '"*.txt"'
my @txt = glob "*.txt"; # recommended
Whitespace splits the pattern#
glob splits its argument on whitespace and treats each segment as a
separate pattern. The results are concatenated:
my @sources = glob "*.c *.h"; # all .c OR .h files
my @all = glob ".* *"; # every entry in cwd
To glob a filename that itself contains spaces, wrap it in an inner pair of quotes so the split sees one segment:
my @spacey = glob '"*e f*"'; # files with "e f" in the name
my @spacey = glob q("*e f*"); # same, q() for clarity
my @spacey = <"*e f*">; # same via the shortcut form
Interpolating a variable into a spacey pattern:
my @spacey = glob "'*${var}e f*'";
my @spacey = glob qq("*${var}e f*");
If the whitespace-splitting rule gets in the way, use
File::Glob’s bsd_glob directly — it takes the
pattern verbatim.
Brace expansion without a wildcard#
If the only special characters are non-empty braces, glob does not
touch the filesystem at all: it just enumerates the Cartesian product
of the alternatives. This is useful for generating string
combinations:
my @pairs = glob "{apple,tomato,cherry}={green,yellow,red}";
# apple=green, apple=yellow, apple=red,
# tomato=green, tomato=yellow, tomato=red,
# cherry=green, cherry=yellow, cherry=red
File::Glob — the engine, and its options#
glob is implemented on top of File::Glob’s
bsd_glob. Importing the module’s tags tunes behaviour for the whole
compilation unit:
:nocase— case-insensitive matching.:case— force case-sensitive matching (the default on most Unix filesystems).:globally— replace the coregloboperator withbsd_globso everyglob(...)and<...>in the file picks up your options.
use File::Glob qw(:globally :nocase);
my @txt = glob "readme*"; # README, readme.txt, Readme.md
Call bsd_glob directly when you need flags per call, or when you
want to bypass the whitespace-splitting rule:
use File::Glob qw(bsd_glob GLOB_TILDE GLOB_BRACE);
my @files = bsd_glob("~/docs/*.{md,rst}", GLOB_TILDE | GLOB_BRACE);
Examples#
List every Perl source file in the current directory:
my @perl_files = glob "*.pl *.pm";
Iterate MP3 files one at a time — useful when the list might be large and you do not want to materialise it:
while (my $song = glob "*.mp3") {
process($song); # one filename per iteration
}
Recursive patterns are not built in; * does not cross /.
Walk the tree with File::Find or combine glob
with an explicit traversal:
my @all_c;
for my $dir (glob "src/*") {
push @all_c, glob "$dir/*.c" if -d $dir;
}
Use the iterator form in a while condition — the result is
assigned to $_ and tested for definedness, so filenames
like "0" do not terminate the loop:
while (<*.log>) {
unlink $_ if -M $_ > 30; # older than 30 days
}
Case-insensitive match for a whole file:
use File::Glob qw(:globally :nocase);
my @readmes = glob "readme*";
Edge cases#
No matches: returns the empty list. No warning, no
$!set. If you need “pattern had to match”, checkscalar @filesyourself.globwith no argument: uses$_. Bareglobinsidewhile (<>)is rarely what you want — the pattern will be whatever line of input you just read.while (glob ...)assigns to$_and tests definedness: a filename"0"is false under normal boolean rules, but the loop still runs because the condition isdefined $_. This matches the rule forreadlinein the same position.Wildcards and whitespace: the split-on-whitespace rule means
glob "a b"searches foraandbas two patterns, not for the literal string"a b". Use inner quotes orbsd_globwhen the filename legitimately contains spaces.Hidden files: a leading
.is not matched by*— you need an explicit.*segment (glob ".* *") to include dotfiles. This matches shell glob semantics, not regex semantics.Tilde expansion:
glob "~/foo"works becauseFile::Globexpands~by default. Writing it throughbsd_globwithoutGLOB_TILDEin the flags, you get a literal~.Interpolation inside
<...>:<$var/*.c>interpolates$varat runtime. Using the angle-bracket form does not escape you from Perl’s normal double-quote rules.Angle-bracket ambiguity:
<FOO>is a handle read,<$foo>is a handle read,<*.c>is a glob.<$foo/*.c>— one scalar plus pattern characters — is a glob. The resolution is compile-time; runtime changes to$foodo not re-decide it.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
opendir— open a directory handle for finer-grained traversal than pattern matching gives youreaddir— read entries from a directory handle one at a time; pair withopendirwhen you need every entry (including onesglobhides, like dotfiles) or file-type inforeadline— the other meaning of<...>; shares the angle-bracket syntax but reads lines from a filehandleFile::Glob— the underlying implementation; usebsd_globdirectly for per-call flags and to bypass the whitespace-splitting rule$_— default pattern source for bareglob, and the variable implicitly assigned whenglobis used as awhile/forloop condition