在 Perl 中使用 Getopt 时如何对参数进行分组?

发布于 10-01 23:45 字数 765 浏览 8 评论 0原文

对于我正在编写的 Perl 脚本,可能会提供很多(~50)个命令行选项。其中大多数都是可选的,因此调用时只会提供部分选项。

我正在使用 Getopt::Long 但它不允许我多次使用 GetOptions 。因此,我必须在一次 GetOptions 调用中使用所有命令行选项。

使用GetOptions时是否有一些好的方法来对选项进行分组?

$ cat test.pl
use strict;
use warnings;
use Getopt::Long;

my ($a, $b, $c, $d);

GetOptions ('a=s' => \$a, 'b=s' => \$b);
GetOptions ('c=s' => \$c, 'd=s' => \$d);

print "a = $a\nb = $b\nc = $c\nd = $d\n";

$ perl test.pl -a=AA -b=BB -c=CC -d=DD
Unknown option: c
Unknown option: d
Use of uninitialized value in concatenation (.) or string at test.pl line 10.
Use of uninitialized value in concatenation (.) or string at test.pl line 10.
a = AA
b = BB
c = 
d = 
$

To a perl script that I am writing, there can be a lot (~50) of command line options provided. Most of them are optional, so a call will have only some of the options provided.

I am using Getopt::Long but it does not allow me to use GetOptions more than once. As a result, I have to use all the command line options in one GetOptions call.

Is there some good way to group the options while using GetOptions?

$ cat test.pl
use strict;
use warnings;
use Getopt::Long;

my ($a, $b, $c, $d);

GetOptions ('a=s' => \$a, 'b=s' => \$b);
GetOptions ('c=s' => \$c, 'd=s' => \$d);

print "a = $a\nb = $b\nc = $c\nd = $d\n";

$ perl test.pl -a=AA -b=BB -c=CC -d=DD
Unknown option: c
Unknown option: d
Use of uninitialized value in concatenation (.) or string at test.pl line 10.
Use of uninitialized value in concatenation (.) or string at test.pl line 10.
a = AA
b = BB
c = 
d = 
$

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

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

发布评论

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

评论(4

汹涌人海2024-10-08 23:45:22

将选项存储在散列中可能是个好主意:

请参阅 Getopt: :Long :将选项值存储在哈希中


有时,例如当有
有很多选择,有一个单独的
他们每个人的变量可以是
麻烦。 GetOptions() 支持,如
另一种机制,存储
哈希中的选项值。

要获得此值,需要引用哈希值
必须作为第一个参数传递
GetOptions()。对于每个选项
在命令行上指定,
选项值将被存储在
以选项名称作为键的哈希值。
实际未使用的选项
命令行不会被放入
换句话说,哈希值
exists($h{option})(或define())可以
用于测试是否使用了某个选项。
缺点是会出现警告
如果程序在使用中运行则发出
strict 并使用 $h{option} 而不
使用 exists()define() 进行测试
首先。

我的 %h = ();
GetOptions(\%h,'长度=i'); # 将存储在$h{length}中

对于采用列表或散列值的选项,它是
有必要通过以下方式表明这一点
在后面添加 @ 或 % 符号
类型:

GetOptions(\%h, 'colors=s@'); # 将推送到@{$h{colors}}

为了让事情变得更复杂,哈希可能
包含对实际内容的引用
目的地,例如:

我的 $len = 0;
我的 %h = ('length' => \$len);
GetOptions(\%h,'长度=i'); # 将存储在 $len 中

此示例完全等同于:

我的 $len = 0;
GetOptions('length=i' => \$len); # 将存储在 $len 中

任何混合物都是可能的。例如,最
经常使用的选项可能是
存储在变量中,而所有其他
选项存储在哈希中:

我的 $verbose = 0; # 经常提到的
我的 $debug = 0; # 经常提到的
我的 %h = ('verbose' => \$verbose, 'debug' => \$debug);
GetOptions(\%h, '详细', '调试', '过滤器', 'size=i');
如果 ( $verbose ) { ... }
if (exists $h{filter} ) { ... 指定了选项 'filter' ... }

It may be a good idea to store your options in a hash instead:

See Getopt::Long : Storing options values in a hash :


Sometimes, for example when there are
a lot of options, having a separate
variable for each of them can be
cumbersome. GetOptions() supports, as
an alternative mechanism, storing
options values in a hash.

To obtain this, a reference to a hash
must be passed as the first argument
to GetOptions(). For each option that
is specified on the command line, the
option value will be stored in the
hash with the option name as key.
Options that are not actually used on
the command line will not be put in
the hash, on other words,
exists($h{option}) (or defined()) can
be used to test if an option was used.
The drawback is that warnings will be
issued if the program runs under use
strict and uses $h{option} without
testing with exists() or defined()
first.

my %h = ();
GetOptions (\%h, 'length=i');       # will store in $h{length}

For options that take list or hash values, it is
necessary to indicate this by
appending an @ or % sign after the
type:

GetOptions (\%h, 'colours=s@');     # will push to @{$h{colours}}

To make things more complicated, the hash may
contain references to the actual
destinations, for example:

my $len = 0;
my %h = ('length' => \$len);
GetOptions (\%h, 'length=i');       # will store in $len

This example is fully equivalent with:

my $len = 0;
GetOptions ('length=i' => \$len);   # will store in $len

Any mixture is possible. For example, the most
frequently used options could be
stored in variables while all other
options get stored in the hash:

my $verbose = 0;                    # frequently referred
my $debug = 0;                      # frequently referred
my %h = ('verbose' => \$verbose, 'debug' => \$debug);
GetOptions (\%h, 'verbose', 'debug', 'filter', 'size=i');
if ( $verbose ) { ... }
if ( exists $h{filter} ) { ... option 'filter' was specified ... }
樱花细雨2024-10-08 23:45:22

最直接的答案是使用 Getopt::Long::Configure,如下所示:

use strict;
use warnings;
use Getopt::Long;

my ($a, $b, $c, $d);

Getopt::Long::Configure( qw(pass_through) );
GetOptions ('a=s' => \$a, 'b=s' => \$b);

Getopt::Long::Configure( qw(no_pass_through) );
GetOptions ('c=s' => \$c, 'd=s' => \$d);

print "a = $a\nb = $b\nc = $c\nd = $d\n";

请注意,您应该确保最后一次调用 GetOptions 应配置为 no_pass_through,以确保收到有关未知的警告选项。

% perl test_getop.pl -a AA -b BB -c CC -d DD -e EE
Unknown option: e
a = AA
b = BB
c = CC
d = DD

The most direct answer is to use Getopt::Long::Configure like so:

use strict;
use warnings;
use Getopt::Long;

my ($a, $b, $c, $d);

Getopt::Long::Configure( qw(pass_through) );
GetOptions ('a=s' => \$a, 'b=s' => \$b);

Getopt::Long::Configure( qw(no_pass_through) );
GetOptions ('c=s' => \$c, 'd=s' => \$d);

print "a = $a\nb = $b\nc = $c\nd = $d\n";

Note that you should make sure that your last invocation of GetOptions should be configured with no_pass_through to make sure that you get warnings about unknown options.

% perl test_getop.pl -a AA -b BB -c CC -d DD -e EE
Unknown option: e
a = AA
b = BB
c = CC
d = DD
装纯掩盖桑2024-10-08 23:45:22

有什么问题:

GetOptions(
  'a=s' => \$a,
  'b=s' => \$b,
  'c=s' => \$c,
  'd=s' => \$d,
);

或者,如果它们都很短,您可以这样做:(

GetOptions(
  'a=s' => \$a,   'b=s' => \$b,
  'c=s' => \$c,   'd=s' => \$d,
);

请注意,将 $a$b 用于除 之外的任何内容都是一个坏主意>排序比较。)

What's wrong with:

GetOptions(
  'a=s' => \$a,
  'b=s' => \$b,
  'c=s' => \$c,
  'd=s' => \$d,
);

Or, if they're all short, you could do:

GetOptions(
  'a=s' => \$a,   'b=s' => \$b,
  'c=s' => \$c,   'd=s' => \$d,
);

(Note that it's a bad idea to use $a and $b for anything except sort comparisions.)

天暗了我发光2024-10-08 23:45:22

通常,数组在传递给函数之前会被展平为单个列表,尽管有些函数会覆盖此行为。使用它,您可以定义选项组数组并将数组列表传递给 GetOptions。

use strict;
use warnings;
use Getopt::Long;

my ( $opt_a, $opt_b, $opt_c, $opt_d );

my @opt_group_1 = ( 'a=s' => \$opt_a, 'b=s' => \$opt_b );
my @opt_group_2 = ( 'c=s' => \$opt_c, 'd=s' => \$opt_d );
GetOptions( @opt_group_1, @opt_group_2 );

print "a = $opt_a\nb = $opt_b\nc = $opt_c\nd = $opt_d\n";

您可以将其与在散列中存储值结合起来,以避免创建大量选项变量,如 Zaid 提到的。

use strict;
use warnings;
use Getopt::Long;

my @opt_group_1 = ( 'a=s', 'b=s' );
my @opt_group_2 = ( 'c=s', 'd=s' );

my %opt;

GetOptions( \%opt, @opt_group_1, @opt_group_2 );

print "a = $opt{a}\nb = $opt{b}\nc = $opt{c}\nd = $opt{d}\n";

Normally arrays are flattened out into a single list before being passed to a function, although some functions override this behavior. Using this you can define arrays of option groups and pass the list of arrays to GetOptions.

use strict;
use warnings;
use Getopt::Long;

my ( $opt_a, $opt_b, $opt_c, $opt_d );

my @opt_group_1 = ( 'a=s' => \$opt_a, 'b=s' => \$opt_b );
my @opt_group_2 = ( 'c=s' => \$opt_c, 'd=s' => \$opt_d );
GetOptions( @opt_group_1, @opt_group_2 );

print "a = $opt_a\nb = $opt_b\nc = $opt_c\nd = $opt_d\n";

You can combine this with storing values in a hash to prevent having to create a huge number of option variables as Zaid mentioned.

use strict;
use warnings;
use Getopt::Long;

my @opt_group_1 = ( 'a=s', 'b=s' );
my @opt_group_2 = ( 'c=s', 'd=s' );

my %opt;

GetOptions( \%opt, @opt_group_1, @opt_group_2 );

print "a = $opt{a}\nb = $opt{b}\nc = $opt{c}\nd = $opt{d}\n";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文