使用Getopt :: Long解析参数的最简洁方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Getopt :: Long解析参数的最简洁方法相关的知识,希望对你有一定的参考价值。

我使用GetOpt来解析命令行参数。我想添加一个新选项“multi”,它应该得到一个字符串,如下所示:key1=abc,key2=123,key3=xwz。我不知道用户想要提供多少个自定义键,但他可以给minimax 5键。另外,我想把它放在带键的哈希中。我正在寻找一种良好而干净的方式来实现它。

首先,我想到使用--multi {key1=abc,key2=123,key3=xwz}但由于某种原因,它只获得第一个关键key1=abc。我也试过:--multi {key1=abc},{key2=123},{key3=xwz}但感觉有点乱。我想让用户可以像-一样使用key1=./some_script.pl --help添加参数。部分代码:

my %arg;
GetOptions(
            "multi=s" => $arg{"multi"},
}

然后我想以某种方式将这些键放在哈希中,这样就可以很容易地使用它们。所以我想使用:$arg{"multi"}{"key3"}以获得key3的值。我该如何处理此功能?最干净的方法是什么?

总结一下:

  1. 要求用户提供密钥以获得与key1=abc,key2=123,key3=xwz类似的情况的最佳方式是什么,而不使用文件(提供选项,而不是以文件方式)?含义 - 作为脚本的用户,您希望如何提供这些字段?
  2. 如何验证用户提供的密钥少于5个?
  3. 我应该如何解析这些键以及将这些键插入multi键中的哈希映射的最佳方法。

预期输出:我想有一个看起来像这样的哈希:$arg{"multi"}{"key3"}并返回xwz

答案

以下程序从命令行上的--multi选项中读取逗号分隔的子选项。

#!perl
use strict;
use warnings;
use Data::Dumper;
use Getopt::Long 'GetOptionsFromArray';

my @args = ('--multi', '{key1=abc,key2=123,key3=xwz}', 'some', 'other');

my %arg;
GetOptionsFromArray(
    @args,
            "multi=s" => $arg{"multi"},
);

if( $arg{multi} and $arg{multi} =~ /^{(.*)}$/) {
    # split up into hash:
    $arg{ multi } = { split /[{},=]/, $1 };
};

print Dumper \%arg;

__END__

$VAR1 = {
          'multi' => {
                       'key2' => '123',
                       'key1' => 'abc',
                       'key3' => 'xwz'
                     }
        };

该程序使用GetOptionsFromArray以便于测试。在实际程序中,您可能会使用与GetOptions(...)相同的GetOptionsFromArray(@ARGV, ...)

另一答案

一种方法是将key=value格式的选项分配给哈希,GetOpt::Long allows。更好的是,由于此功能仅需要哈希引用,因此可以将其分配给hashref,该哈希值是更深层数据结构中的值。你可以直接使用它

use warnings;
use strict;
use feature 'say';

use Getopt::Long;
use Data::Dump qw(dd);

my %args;
$args{multi} = {}; 

GetOptions( 'multi=s' => $args{multi} ) or die "Bad options: $!";

dd \%args;

通过多次调用该选项,可以添加键值对

script.pl --multi k1=v1 --multi k2=v2

并打印上述程序

{ multi => { k1 => "v1", k2 => "v2" } }

我使用Data::Dump来打印复杂的数据。如果这是一个问题,请更改为核心Data::Dumper

虽然Getopt::Long有一种方法来限制一个选项所采用的参数数量,这显然只适用于数组目的地。所以你必须计算钥匙来检查。

另一种方式是process the input string in a subroutine,你几乎可以做任何你想做的事情。将其添加到上面的脚本中,将另一个带有hashref的键添加到%args

use warnings;
use strict;
use feature 'say';

use Getopt::Long;
use Data::Dump qw(dd);

my %args;
$args{multi} = {};

GetOptions(
    'multi=s' => $args{multi},
    'other=s' => sub { $args{other} = { split /[=,]/, $_[1] }  }
) or die "Bad options: $!";

dd \%args;

当被称为

script.pl --multi k1=v1 --multi k2=v2  --other mk1=mv1,mk2=mv2

这打印

{
  other => { mk1 => "mv1", mk2 => "mv2" },
  multi => { k1 => "v1", k2 => "v2" },
}

以上是关于使用Getopt :: Long解析参数的最简洁方法的主要内容,如果未能解决你的问题,请参考以下文章

命令行参数解析函数getopt和getopt_long函数

Perl模块 Getopt::Long 解析

使用getopt_long来解析参数的小函数模板

getopt()和getopt_long函数

[总结]函数getopt(),getopt_long及其参数optind

C命令行参数解析——getoptgetopt_long及getopt_long_only