我希望在perl脚本中写下接收和选项的值列表以双短划线( - )结尾。 例如:
% perl_script -letters a b c -- -words he she we --
作为运行此命令行的结果,将创建两个数组: 字母= [a b c]; words = [他是我们];
使用GetOption不支持此功能,b.c在使用双短划线后,选项识别停止。
答案 0 :(得分:5)
您是否有某些特定理由使用这种令人困惑的分隔符? --
对大多数脚本用户都有一个已知的含义,这不是它。
如果你需要读入带有列表的选项,Getopt::Long
有处理输入数组的方法,也许这样的东西可以帮助你;看看"Options with multiple values"下。此模块属于标准发行版,因此您甚至无需安装任何内容。我将它用于需要多个(可能是两个)输入的任何脚本,如果任何输入是可选的,那么它肯定是。
以下是一个简单的示例,如果您可以灵活地更改输入语法,则可以获得您要求的功能:
#!/usr/bin/env perl
# file: test.pl
use strict;
use warnings;
use Getopt::Long;
my @letters;
my @words;
GetOptions(
"letters=s{,}" => \@letters,
"words=s{,}" => \@words
);
print "Letters: " . join(", ", @letters) . "\n";
print "Words: " . join(", ", @words) . "\n";
给出:
$ ./test.pl --letters a b c --words he she we
Letters: a, b, c
Words: he, she, we
虽然我永远不会鼓励编写自己的解析器,但我无法理解为什么有人会选择你的表单,所以我会假设你不能控制这种格式并需要解决它。如果是这种情况(否则,请考虑更标准的语法并使用上面的示例),这里有一个简单的解析器,可以帮助您入门。
N.B。不写自己的原因是其他人经过了充分的测试,并且已经解决了边缘情况。你也知道你会对--
和-title
之间的某些事情做些什么吗?我认为,因为新标题会结束前一个标题,所以你可能会介入其中一些东西并将所有这些按顺序集中在一个“默认”密钥中。
#!/usr/bin/env perl
# file: test_as_asked.pl
# @ARGV = qw/default1 -letters a b c -- default2 -words he she we -- default3/;
use strict;
use warnings;
my %opts;
# catch options before a -title (into group called default)
my $current_group = 'default';
foreach my $opt (@ARGV) {
if ($opt =~ /\-\-/) {
# catch options between a -- and next -title
$current_group = 'default';
} elsif ($opt =~ /\-(.*)/) {
$current_group = $1;
} else {
push @{ $opts{$current_group} }, $opt;
}
}
foreach my $key (keys %opts) {
print "$key => " . join(", ", @{ $opts{$key} }) . "\n";
}
给出:
$ ./test_as_asked.pl default1 -letters a b c -- default2 -words he she we -- default3
letters => a, b, c
default => default1, default2, default3
words => he, she, we
答案 1 :(得分:3)
怎么样
-letters "a b c" -words "he she we"
答案 2 :(得分:2)
如果需要,您可以在多个通道中处理您的参数。查看pass_through选项。这就是我在ack中所做的,因为有些选项会影响其他选项,所以我必须首先处理--type选项,然后处理其余选项。
答案 3 :(得分:0)
禁用 dash dash 后门是不好的做法。