在 Perl 中使用 Getopt::Long 获取多维数据结构

发布于 2024-12-18 06:19:44 字数 836 浏览 1 评论 0原文

我让下面的代码可以根据需要工作,但想知道是否有更好的方法来执行此操作而不使用引号。

myScript.pl --filter 'key1 foo bar' --filter 'key2 baz qux'

#!/usr/local/bin/perl5.8.8
use warnings;
use strict;
use Getopt::Long;
use Data::Dumper;

my %filter;

GetOptions("filter=s" => sub { my @args = split(/\s/, $_[1]); $filter{$args[0]}{value1} = $args[1]; $filter{$args[0]}{value2} = $args[2]; });

print Dumper %filter;

我得到了令人满意的输出:

$VAR1 = 'key2';
$VAR2 = {
          'value1' => 'baz',
          'value2' => 'qux'
        };
$VAR3 = 'key1';
$VAR4 = {
          'value1' => 'foo',
          'value2' => 'bar'
        };

但是,我想像这样使用它,不带引号:

myScript.pl --filter key1 foo bar --filter key2 baz qux --other_option ...

key1 和 key2 是这里的哈希键,并且是唯一的。

有什么想法/建议吗?

I got this code below to work as I need, but would like to know if there's a better way of doing this without quotes.

myScript.pl --filter 'key1 foo bar' --filter 'key2 baz qux'

#!/usr/local/bin/perl5.8.8
use warnings;
use strict;
use Getopt::Long;
use Data::Dumper;

my %filter;

GetOptions("filter=s" => sub { my @args = split(/\s/, $_[1]); $filter{$args[0]}{value1} = $args[1]; $filter{$args[0]}{value2} = $args[2]; });

print Dumper %filter;

I get a satisfactory output:

$VAR1 = 'key2';
$VAR2 = {
          'value1' => 'baz',
          'value2' => 'qux'
        };
$VAR3 = 'key1';
$VAR4 = {
          'value1' => 'foo',
          'value2' => 'bar'
        };

However, I would like to use it like this, without quotes:

myScript.pl --filter key1 foo bar --filter key2 baz qux --other_option ...

key1 and key2 are hash keys here and will be unique.

Any ideas/suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦巷 2024-12-25 06:19:44

当我上次检查时(几年前),没有一个 20-30 Getopt 模块将处理一串参数,而我所知道的大多数基于 C 的参数解析代码也无法处理该问题。 (我确实有一个 C 代码解析器可以处理它,前提是您知道要使用多少个参数。目前尚不清楚您是否需要 1 个键和 2 个值,或者值列表是否可以比这更可变。


)可能是我看的不够仔细。

Getopt::Long 有选项:

警告:以下是实验性功能。

例如,选项可以一次采用多个值

--坐标 52.2 16.4 --rgbcolor 255 255 149

这可以通过向选项规范添加重复说明符来实现。重复说明符与可与正则表达式模式一起使用的 {...} 重复说明符非常相似。例如,上面的命令行将按如下方式处理:

GetOptions('坐标=f{2}' => \@coor, 'rgbcolor=i{3}' => \@color);

选项的目标必须是数组或数组引用。

还可以指定选项所采用的参数的最小和最大数量。 foo=s{2,4} 表示一个选项至少有两个,最多有 4 个参数。 foo=s{,} 表示一个或多个值; foo:s{,} 表示零个或多个选项值。

这将生成一个包含键和两个值的数组。鉴于这需要与具有多个条目的能力相结合(每个 --filter 一个),您可能仍然不走运,但您应该探索 Getopt::Long代码> 非常仔细。

When I last checked (a couple of years ago), none of the 20-30 Getopt modules listed on CPAN would handle a string of arguments as you show, and most of the C-based argument parsing code I know of does not handle that either. (I do have a C code parser that handles it, provided you know how many arguments to consume. It is not clear whether you require 1 key and 2 values or whether the list of values can be more variable than that.)


Maybe I didn't look carefully enough.

Getopt::Long has the option:

Warning: What follows is an experimental feature.

Options can take multiple values at once, for example

--coordinates 52.2 16.4 --rgbcolor 255 255 149

This can be accomplished by adding a repeat specifier to the option specification. Repeat specifiers are very similar to the {...} repeat specifiers that can be used with regular expression patterns. For example, the above command line would be handled as follows:

GetOptions('coordinates=f{2}' => \@coor, 'rgbcolor=i{3}' => \@color);

The destination for the option must be an array or array reference.

It is also possible to specify the minimal and maximal number of arguments an option takes. foo=s{2,4} indicates an option that takes at least two and at most 4 arguments. foo=s{,} indicates one or more values; foo:s{,} indicates zero or more option values.

This would generate an array with the key and two values in it. Given that this needs to be combined with the ability to have multiple entries (one per --filter), you may still be out of luck, but you should explore Getopt::Long excruciatingly carefully.

夏了南城 2024-12-25 06:19:44

您可以使用选项名称 <> 指定非选项参数的回调,并适当调整您的 %filters 哈希值,如下所示:

GetOptions('filter=s' =>  \&set_filter, '<>' => \&non_option);

我想象您的 @ARGV除非你使用 -- ,否则最终会是空的。

You may specify a callback for non-option arguments using the option name <> and adjust your %filters hash appropriately, like this :

GetOptions('filter=s' =>  \&set_filter, '<>' => \&non_option);

I'd imagine your @ARGV would end up empty unless you use a -- though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文