Getopt::Long
简单解析@ARGV
列表作为提供到Perl程序。如果@ARGV
列表中的参数是单独的条目,则Getopt::Long
将以这种方式解析它们。你的问题是shell将每个参数作为一个单独的参数,因为它们周围没有引号。
您的选择是你的Perl脚本运行之前,或改写(munging)@ARGV
本身的参数组合成他们假设是在值要么Munge时间参数。
对于第一种选择,你可以使用sed
将您的程序输出并添加缺少的引号。如果你是程序总是吐出领域是这样的:
prog_name -filter_arg +define BOOST +noconvtest +actuate-long -disp_arg +define size=40 res=30
,你可以管,通过sed
这样的:
$ orig_prog | sed -e 's/filter_arg /filter_arg "/' -e 's/ -disp_arg /" -disp_arg "/' -e 's/$/"/'
或者这样:
$ orig_prog | sed -e 's/^\(.*\) -filter_arg \(.*\) -disp_arg \(.*\)$/\1 -filter_arg "\2" -disp_arg "\3"/'
,将放在引号围绕您的参数,它将如下所示:
prog_name -filter_arg "+define BOOST +noconvtest +actuate-long" -disp_arg "+define size=40 res=30"
这样,@ARGV
将正确设置,因此GetOptions
函数将以您希望的方式工作。
的另一种方式是Munge时间@ARGV
一旦你打电话之前Perl程序运行GetOptions
:
my $value;
my @newArgv;
foreach my $param (@ARGV) {
if ($param =~ /^-/) {
if ($value) {
push (@newArgv, $value);
$value = "";
}
push(@newArgv, $param);
} else {
$value = $value ? "$value $param" : "$param";
}
}
push (@newArgv, $value) if ($value);
@ARGV = @newArgv;
在上面的例子中,@ARGV
将具有以下值:
@ARGV[0] = -filter_arg
@ARGV[1] = +define BOOST +noconvtest +actuate-long
@ARGV[2] = -disp_arg
@ARGV[3] = +define size=40 res=30
而且,Getopts::Long
现在应该按照您希望的方式工作。 有点旁注:在较新版本的Getopt::Long
中,除了@ARGV
之外,您还可以使用其他数组。你只需把你想要作为第一个参数使用数组中GetOptions
:
use Getopt::Long qw(GetOptionsFromArray);
GetOptionsFromArray (
\@newArgs,
"filter_arg=s" => \$filter_arg,
"disp_arg=s" => \$disp_arg,
);
非常感谢Axeman,David和Colin。非常感谢您的及时回应。按照Perl的真实精神,您已经展示了如何以多种方式解决问题!我仔细了解了您的每一个帖子后,我学到了很多东西。温暖的问候。 – Silver2010 2010-11-24 03:25:38