Zaid
Zaid

Reputation: 37146

Is there a way to get Perl to support wildcard command-line arguments like "*.txt" on Windows?

When passing wildcard arguments to a Perl script on *nix systems, like

$ perl script.pl *.txt

shells like Bash will expand all wildcard (*, ?, []) matches, consequently populating @ARGV with all matches.

Windows CMD, however, doesn't perform such an expansion before running the Perl interpreter.

Is it possible to get Perl to handle this expansion internally to mimic *nix shells?

Upvotes: 3

Views: 1233

Answers (2)

ikegami
ikegami

Reputation: 386386

Core module File::DosGlob provides the tools to expand wildcards in the manner a Windows user would expect, so it's just a question to use the glob provided by this module as follows:

use File::DosGlob qw( glob );

@ARGV = map glob, @ARGV;

Note that doing this using the builtin glob would break paths that contain spaces, a relatively common occurrence on Windows. It would also mishandle *.*, which is expected to return all files.

Note that it's best to expand the patterns after processing command-line options to avoid risking expanding the pattern into a command-line option.

use File::DosGlob qw( glob );
use Getopt::Long  qw( GetOptions );

GetOptions(...)
   or die_usage();

@ARGV = map glob, @ARGV;

For a one-liner, you could use the following:

perl -MFile::DosGlob=glob -ne"BEGIN { @ARGV = map glob, @ARGV } ..." ...

The BEGIN ensures the code is run before the input-reading loop created by -n starts.

Upvotes: 3

Zaid
Zaid

Reputation: 37146

glob supports wildcard expansion, so use one can use it to alter @ARGV on the fly:

BEGIN { @ARGV = map +glob, @ARGV; }

Running inside the BEGIN block ensures that @ARGV is modified before the rest of the code is even parsed, let alone run:

A BEGIN code block is executed as soon as possible, that is, the moment it is completely defined, even before the rest of the containing file (or string) is parsed.

Upvotes: 2

Related Questions