>当将通配符参数传递给 *nix 系统上的 Perl 脚本时,例如
$ perl script.pl *.txt
像 Bash 这样的 shell 会扩展所有通配符(*
、?
、[]
)匹配,从而用所有匹配填充@ARGV
。
但是,Windows CMD在运行Perl解释器之前不会执行这样的扩展。
是否有可能让 Perl 在内部处理这种扩展来模仿 *nix shell?
核心模块 File::D osGlob 提供了以 Windows 用户期望的方式扩展通配符的工具,因此使用此模块提供的glob
只是一个问题,如下所示:
use File::DosGlob qw( glob );
@ARGV = map glob, @ARGV;
请注意,使用内置glob
执行此操作会破坏包含空格的路径,这在 Windows 上相对常见。它还会错误地处理*.*
,预计会返回所有文件。
请注意,最好在处理命令行选项后扩展模式,以避免将模式扩展为命令行选项的风险。
use File::DosGlob qw( glob );
use Getopt::Long qw( GetOptions );
GetOptions(...)
or die_usage();
@ARGV = map glob, @ARGV;
对于单行,您可以使用以下内容:
perl -MFile::DosGlob=glob -ne"BEGIN { @ARGV = map glob, @ARGV } ..." ...
BEGIN
可确保在-n
创建的输入读取循环启动之前运行代码。
glob
支持通配符扩展,因此可以使用它来动态更改@ARGV
:
BEGIN { @ARGV = map +glob, @ARGV; }
在BEGIN
块内运行可确保在解析代码的其余部分之前修改@ARGV
,更不用说运行了:
BEGIN
代码块会尽快执行,也就是说,在完全定义的那一刻,甚至在解析包含文件(或字符串)的其余部分之前。