我希望在 perl 脚本中写下以双破折号 (--) 结尾的值列表的接收和选项。例子:
% perl_script -letters a b c -- -words he she we --
作为运行此命令行的结果,将创建两个数组: letters = [abc ]; words = [他她我们];
使用 GetOption 不支持这一点,bc 在使用 double dash 之后,选项识别停止。
您是否有特定的理由使用这种令人困惑的分隔符?--
对于大多数脚本用户来说,它具有已知的含义,但事实并非如此。
如果您需要读取带有列表的选项,Getopt::Long
具有处理输入数组的方法,也许这样的东西可以帮助您;在“具有多个值的选项”下查看。这个模块在标准发行版中,所以你甚至不需要安装任何东西。我将它用于需要多个(可能两个)输入的任何脚本,并且肯定是否有任何输入是可选的。
这是一个简单的示例,如果您可以灵活地更改输入语法,这将为您提供所需的功能:
#!/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
虽然我永远不会鼓励编写自己的解析器,但我不明白为什么有人会选择你所拥有的形式,所以我将在你无法控制这种格式并且需要解决它的假设下进行操作。如果是这种情况(否则,请考虑更标准的语法并使用上面的示例),这里有一个简单的解析器,可以帮助您入门。
注意不自己写的原因是其他人经过了很好的测试并且已经解决了边缘案例。你也知道你会用 a--
和 a之间的东西做什么-title
吗?我假设由于新的 -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
怎么样
-letters "a b c" -words "he she we"
?
如果需要,您可以多次处理您的参数。查看 pass_through 选项。这就是我在ack中所做的,因为某些选项会影响其他选项,所以我必须先处理 --type 选项,然后再处理其余的。
禁用破折号后门是不好的做法。