【问题标题】:Can I bind two different input flags using Getopt::Long lib in perl?我可以在 perl 中使用 Getopt::Long lib 绑定​​两个不同的输入标志吗?
【发布时间】:2020-08-11 11:58:56
【问题描述】:

让我们举一个简单的例子:我希望在我的脚本中有以下输入:

[
{foo => date_1},
{foo2=> date_2},
{foo3=> undef}, # there was no input
... # probably more in the future
]

所以使用类似的东西:

use strict;
use warnings;
use utf8;
use Getopt::Long qw(GetOptions);

my @foos;
my @dates;

# INPUT
GetOptions(
    'foo|f:s'                                       => \@foos,
    'date|d:s'                                      => \@dates,
# 'help|h'   => \&help,
) or die "Invalid options passed to $0\n"; 

我希望能够使用类似于以下内容的方式调用脚本:

perl script.pl --foo "Go with 1" --foo "Go with 2" --date "date1" --date "date2"

然后能够做类似的事情:

foreach my $i (0..scalar(@foos)){
  print $foos[$i] . " " . $dates[$i] . "\n";
}

并获得:

Go with 1 date1
Go with 2 date2

我为什么要这样做?:我为一个函数循环了不确定数量的foos。在另一个函数中,我想再次循环遍历 foos 并打印与之关联的日期如果存在

我想避免的事情:必须为 foos 的每个元素创建一个标志,如下所示:

GetOptions(
    'foo|f:s'                                               => \@foos,
    'date-foo-1|df1:s'                                      => \$dates_foo_1,
    'date-foo-2|df2:s'                                      => \$dates_foo_2,
# 'help|h'   => \&help,
) or die "Invalid options passed to $0\n"; 

我想我能做的是将一个可选标志与另一个标志相关联,但我找不到任何相关的东西。

【问题讨论】:

    标签: perl hash binding getopt-long


    【解决方案1】:

    您的代码已经完成了您想要的操作。

    use strict;
    use warnings;
    use utf8; # This is unnecessart
    use Getopt::Long qw(GetOptions);
    
    my @foos;
    my @dates;
    
    # INPUT
    GetOptions(
        'foo|f:s'  => \@foos,
        'date|d:s' => \@dates,
    # 'help|h'   => \&help,
    ) or die "Invalid options passed to $0\n";
    
    foreach my $i (0 .. scalar(@foos)){
      print $foos[$i] . " " . $dates[$i] . "\n";
    }
    

    输出是:

    Go with 1 date1
    Go with 2 date2
    Use of uninitialized value in concatenation (.) or string at opts.pl line 17.
    Use of uninitialized value in concatenation (.) or string at opts.pl line 17.
    

    显示警告是因为您的数组遍历代码存在错误。你不想走0 .. scalar @foos,因为scalar @foos 给出2,@foos 中的最高索引是1。

    您可以使用$#foos 代替scalar @foos 来获取@foos 中的最高索引。

    foreach my $i (0 .. $#foos){
      print $foos[$i] . " " . $dates[$i] . "\n";
    }
    

    还需要指出

    print $foos[$i] . " " . $dates[$i] . "\n";
    

    可以更简单地写成:

    print "$foos[$i] $dates[$i]\n";
    

    更新:在您需要两个相同长度的列表的情况下,您还可以查看Options with hash values 的文档

    【讨论】:

    • 问题是,只要所有日期都有一个值,它就会起作用,但是如果我想在第三个和第一个选项中有一个日期,它将不起作用,作为第三个选项将转移到第二个选项,产生不希望的结果。
    • @nck:那么我认为您需要查看哈希选项,不是吗?
    • 如果我错了,请纠正我,但我认为哈希值选项允许您将一组选项存储到哈希中,但它只是将输入参数的子集放入哈希中, 并没有解决参数不匹配的问题
    • 我认为您必须更改参数的工作方式:--item foo=date1 --item foo2=date2 --item foo3= 等...
    • unfertonetaly 这种方法不是真正可扩展的,对用户来说也不直观:(
    猜你喜欢
    • 1970-01-01
    • 2010-10-06
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多