【问题标题】:perl parsing command-line arguments [closed]perl解析命令行参数
【发布时间】:2011-08-15 19:22:27
【问题描述】:

我需要编写一个接受可以连接的命令行参数的 perl 程序 例如

myPerl.pl -l -c -d    same as    myPerl.pl  -lcd

唯一的限制是我不能使用诸如“Getopts”之类的内置模块,任何人都知道我可以做些什么来轻松实现这一点。

【问题讨论】:

  • 为什么不能使用模块?它们旨在解决这些问题,那么为什么要重新发明轮子呢?
  • 除非这是家庭作业,否则您应该使用Getopt::Long 或类似模块。 Getopt::Long 是核心 Perl 发行版的一部分,因此几乎可以保证它可用。

标签: perl concatenation command-line-arguments


【解决方案1】:

查看Bundling下的Getopt::Long

更新:哦,没有模块。这是家庭作业。那么,把Getopt::Long中的代码复制出来。

【讨论】:

  • +1 表示“从 Getopt::Long 中复制代码”
【解决方案2】:

没有个模块? 真的吗?这就像 so perl4。 :)

好吧,这就是我们在 perl4 中的一贯做法:

ARG: while (@ARGV && $ARGV[0] =~ s/^-(?=.)//) {
OPT:    for (shift @ARGV) {

            m/^$/        && do {                                 next ARG; };
            m/^-$/       && do {                                 last ARG; };

            s/^0//       && do { $nullpaths++;                   redo OPT; };
            s/^f//       && do { $force++;                       redo OPT; };
            s/^l//       && do { $reslinking++;                  redo OPT; };
            s/^I//       && do { $inspect++;                     redo OPT; };
            s/^i//       && do { $careful++;                     redo OPT; };
            s/^v//       && do { $verbose++;                     redo OPT; };
            s/^V//       && do { $verbose += 2;                  redo OPT; };  # like two -v's
            s/^m//       && do { $renaming++;                    redo OPT; };
            s/^n//       && do { $nonono++;                      redo OPT; };
            s/^N//       && do { $nonono += 2;                   redo OPT; };  # like two -n's
            s/^q//       && do { $quiet++;                       redo OPT; };

            s/^F(.*)//s  && do { push @flist, $1 || shift @ARGV; redo OPT; };

            &usage("Unknown option: $_");
        }
    }

这不是膨胀吗? :)

同样的方法今天仍然有效,但它可能会引起您的讨论。

【讨论】:

    【解决方案3】:

    可靠地解析参数并不容易,这就是为什么Getopts::* 列表中有无数模块(在这种情况下,无数 ≈ 180)。有很多可能的约定需要处理。在您显示的示例命令行中,最后一个参数 (-lcd) 应该被视为一个选项还是像“same”、“as”、“myPerl.pl”参数这样的文件? 'same' 是 -d 选项的参数,还是单独的 'file name' 选项?单字母选项可以分组吗?参数可以附加到选项吗?它们必须附加吗?他们必须分开吗?您有多个字母选项还是只有单个字母选项?

    在您定义了诸如此类的问题 - 以及如何处理“-”和“--”之前 - 你无法开始编写代码的体面工作。

    您可能会找到这些使用问题的答案:

    【讨论】:

    • 感谢您的回答,不胜感激。
    【解决方案4】:

    我同意,你应该使用模块。无论如何,这是您可以建立的一种尝试:

    use strict;
    use warnings;
    my @opts = grep /^-\w+/, @ARGV;
    print "(1) @opts\n" if @opts;
    my @normalized = sort grep /\w/, map { split /(-|)/ } @opts;
    print "(2) @normalized\n" if @normalized;
    

    【讨论】:

    • 这太酷了。如果您能稍微解释一下您的@normalized 部分是否可以,对于像我这样的初学者来说有点深奥。但无论如何,非常感谢,这太棒了。
    • 嗯,@normalized 是一个处理步骤的管道。从右到左阅读。首先,@opts 可以有-x-yyy 之类的东西。我们希望将所有内容标准化为xy,因为这样我们就可以统一对待它。我们使用split 分割- 或空字符串。此split 的返回值是单个字母或空字符串的列表。我们使用map 将此操作应用于每个元素。我们使用grep 过滤掉空字符串。然后我们sort它,只是为了整洁。然后我们称之为@normalized。 - 不过,请考虑为这种事情使用标准模块。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-21
    • 2012-01-26
    相关资源
    最近更新 更多