如何检查 Perl 中传递的命令行参数的数量?

发布于 2025-01-16 12:03:41 字数 536 浏览 2 评论 0原文

我有一个按以下方式运行的脚本:

perl testing.pl -grid 24 -range 97   ## Here, arguments passed are processed via getopt::Long module.

现在,我想检查传递给脚本的命令行参数的数量。预期是 2。但我得到 0。

我在脚本 (testing.pl) 中使用了下面的代码来提取参数数量:

my $totalCmdLineArg = $#ARGV + 1;
print "$totalCmdLineArg is total command line arguments\n";
if ($totalCmdLineArg <= 0 ) {
    $defaultmode=1;
} else {
    $defaultmode=0;
}

在这里,我得到“0 是命令行参数总数”作为输出。我希望“2 是总命令行参数”作为输出。我怎样才能得到预期的答案?

注意:有 100 多个参数,其中任何一个都可以传递。

I have a script that runs in the following way:

perl testing.pl -grid 24 -range 97   ## Here, arguments passed are processed via getopt::Long module.

Now, I want to check the number of command-line arguments passed to the script. Expected is 2. But I am getting 0.

I used below piece of code inside the script (testing.pl) to extract the number of arguments:

my $totalCmdLineArg = $#ARGV + 1;
print "$totalCmdLineArg is total command line arguments\n";
if ($totalCmdLineArg <= 0 ) {
    $defaultmode=1;
} else {
    $defaultmode=0;
}

Here, I am getting "0 is total command line arguments" as output. I would want "2 is total command line arguments" as output. How can I get the expected answer?

Note: There are 100+ arguments out of which any can be passed.

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

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

发布评论

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

评论(2

2025-01-23 12:03:41

调用 GetOptions 后,您无法对选项进行计数。 GetOptions@ARGV 中删除它识别的选项。引用其文档

命令行选项取自数组@ARGV。完成 GetOptions 后,@ARGV 将包含命令行的其余部分(即非选项)。

此外,GetOptions 不会计算它解析的选项数量。如果您需要说服力,请查看来源

因此,如果您想计算传递给程序的选项数量,您必须在调用 GetOptions 之前手动执行此操作。

如果命令行上的所有参数都采用 --option xxx 形式,那么您可以简单地执行以下操作(调用 GetOptions 之前)

my $totalCmdLineArg = grep { /^--/ } @ARGV

: ,这忽略了 -- 本身在 @ARGV 中标记选项列表结尾的事实。如果您的命令行类似于 perl prog.pl --opt1 v1 --opt2 v2 -- some extra --arguments 那么 ----arguments 实际上不是选项(对于 GetOptions)。要处理这种情况,您必须编写类似以下内容的内容:

my $totalCmdLineArg = 0;
for (@ARGV) {
    last if $_ eq '--';
    $totalCmdLineArg++ if /^--/;
}

但是,这并不能说明单个 - 可用于启动选项,并且可用于组合多个选项($Getopt::Long::bundling 为非零)。您必须调整上面的代码来处理这种情况。


仅在最后手段(不要在生产中使用,可能随时崩溃):
如果您正在使用 bundlingGetopt::Long 的其他复杂功能,您可以稍微修改一下来计算有多少个 Getopt::Long 选项实际上发现。在内部,GetOptions 调用 FindOption 来实际查找选项。您可以重新定义它来计算找到的选项数量:

my $opt_count = 0;
{
  no warnings qw(redefine prototype);
  my $original_FindOption = \&Getopt::Long::FindOption;
  *Getopt::Long::FindOption = sub {
    my @ret = &$original_FindOption;
    if ($ret[0] && defined $ret[1]) {
      $opt_count++;
    }
    return @ret;
  };
}

请注意,这是一种非常脆弱的方法:FindOption 不是 Getopt::Long 公开的 API 的一部分,并且因此,版本之间可能会发生变化,这可能会破坏此代码。

You can't count options after GetOptions has been called. GetOptions removes the options it recognizes from @ARGV. Quoting its documentation:

The command line options are taken from array @ARGV. Upon completion of GetOptions, @ARGV will contain the rest (i.e. the non-options) of the command line.

Furthermore, GetOptions does not count how many options it parses. Check out the source if you need convincing.

So, if you want to count how many options were passed to your program, you have to do it manually, before calling GetOptions.

If all of the arguments on your command line have the form --option xxx, then you can simply do (before calling GetOptions):

my $totalCmdLineArg = grep { /^--/ } @ARGV

However, this ignores the fact that -- on itself in @ARGV marks the end of the option list. If your command line is something like perl prog.pl --opt1 v1 --opt2 v2 -- some additional --arguments then -- and --arguments are actually not options (for GetOptions). To handle this case, you'd have to write something like:

my $totalCmdLineArg = 0;
for (@ARGV) {
    last if $_ eq '--';
    $totalCmdLineArg++ if /^--/;
}

However, this does not account for the fact that a single - can be used to start an option, and that this can be used to combine multiple options (is $Getopt::Long::bundling is non-zero). You'll have to adapt the code above to handle this case.


Only in last resort (do not used in production, might break at any time):
If you are using bundling and other complex features of Getopt::Long, you could hack a bit to count how many options Getopt::Long actually finds. Internally, GetOptions calls FindOption to actually find options. You could redefine it to count how many options are found:

my $opt_count = 0;
{
  no warnings qw(redefine prototype);
  my $original_FindOption = \&Getopt::Long::FindOption;
  *Getopt::Long::FindOption = sub {
    my @ret = &$original_FindOption;
    if ($ret[0] && defined $ret[1]) {
      $opt_count++;
    }
    return @ret;
  };
}

Note that this is a very fragile approach: FindOption is not part of the exposed API of Getopt::Long, and could thus change between versions, which could break this code.

红墙和绿瓦 2025-01-23 12:03:41

四个个参数。二是选项的数量。

GetOptions 不提供找到的选项数量,但有一个简单而干净的方法可以做到这一点。首先,使用 GetOptions( HASHREF, ... ) 调用约定。那么,这只是一个计算哈希中元素数量的问题。

GetOptions( \my %opts,
   "grid=i",
   "range=i",
   ...
)
   or usage();

my $num_options = keys( %opts );

该解决方案适用于所有类型的选项(带值、不带值、捆绑等)。它甚至避免计算重复项。

与之前的答案不同,此解决方案不需要在调用者中重新实现GetOptions(之前的答案做得很糟糕,它声称OP的示例perltesting.pl -grid 24 -range 977 包含零个选项)或猴子修补模块。

There are four arguments. Two is the number of options.

GetOptions doesn't provide the number of options found, but there's a nice easy and clean way to do this. First, use the GetOptions( HASHREF, ... ) calling convention. Then, it's simply a question of counting the number of elements in the hash.

GetOptions( \my %opts,
   "grid=i",
   "range=i",
   ...
)
   or usage();

my $num_options = keys( %opts );

This solution works with all kinda of options (with values, without values, bundled, etc). It even avoids counting duplicates.

Unlike the earlier answer, this solution doesn't require reimplementing GetOptions in the caller (which the earlier answer does so badly, it claims the OP's example perl testing.pl -grid 24 -range 977 contains zero options) or monkey patching the module.

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