37

我需要解析一个命令行

  script.rb <mandatory filename> [options]

optparse

当然我可以编写一些自定义代码来处理文件名,然后传递ARGV给 optparse,但也许有更简单的方法可以做到这一点?

编辑:还有另一种 hacky 方法来解析这样的命令行,那就是传递['--mandatory-filename'] + ARGV给 optparse,然后处理--mandatory-filename选项。

4

5 回答 5

52

首先parse!使用 optparse,然后扫描 ARGV 并在 ARGV 为空时引发。像这样:

op.parse!
filename = ARGV.pop
raise "Need to specify a file to process" unless filename

强制文件名将不会被处理,OptionParser并将在 ARGV 中留给您 - 如果它不存在,只需手动提升。

于 2010-03-15T18:21:48.473 回答
12

只是为了跟进 Julik 和 Shadowfirebird 所说的话:解析时OptionParser要注意这一点parse!parse具有不同的功能。前者将从传递的数组中删除它理解的每个参数,后者将保留它们。这会改变您确定所需参数是否存在的条件。

于 2010-04-06T19:25:52.223 回答
9

虽然它并不适用于所有情况,但能够在单个命令行上处理多个文件通常很不错,例如:

script.rb [options] file1 file2 ...

file1 是必需的,但 file2 及以后是可选的。

我知道的最好的方法是遵循这个约定:

options = {}
optparse = OptionParser.new do |opts|
  opts.banner = "Usage: script.rb [options] file1 file2 ..."

  opts.on('-a', '--an-option ARG', 'Set some option') do |arg|
    options[:a] = arg
  end

  ...
end
optparse.parse!

# Check required conditions
if ARGV.empty?
  puts optparse
  exit(-1)
end

如果未提供文件,将显示一条帮助消息,其中包含使用横幅和选项说明。如果文件存在,它们将是 ARGV 中唯一剩下的东西。

于 2011-04-06T03:18:46.130 回答
2

我不确定它是否是最近添加的,但之前的答案都没有提到optparse.parse在删除解析的选项后将返回 ARGV 值。

如果你这样做:

rest = optparse.parse!

您将获得一个包含给定文件的数组(以及未知选项)。这样您就不必关心选项是在文件之前还是之后。

于 2016-05-06T16:09:24.163 回答
0

Optparse 只做带参数的参数,AFAIK。处理文件名的“正确”方法是在 optparse 之外处理它。我为此发布了一些示例代码来回答这个问题。

顺便说一句,这是一个相当不寻常的命令行。如果它只适合你,很好,但其他人可能会觉得它相当违反直觉。有以下情况会更正常:script.rb [options] <filename>...

于 2010-03-15T21:19:19.017 回答