2010-03-15 25 views
24

解析参数没有名字,我需要分析一个命令行像如何使用Ruby的optparse

script.rb <mandatory filename> [options] 

optparse

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

编辑:有另一种哈克的方式来解析这样的命令行,并通过['--mandatory-filename'] + ARGV optparse,然后处理--mandatory-filename选项。

+0

看到下面的答案,肯定;然而,我会建议你交换你的“强制文件名”和“选项”参数。通常,非切换参数最后在命令行中出现,除非您有其他原因不这样做 – 2011-12-27 13:24:36

回答

38

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

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

强制性文件名不会被OptionParser处理,但留给你ARGV - 如果它不存在,只是人工饲养。

+1

使用类似'op.banner + ='''来相应地调整'Usage:'行。如果我们想扩展到多个所需的参数, – sschuberth 2015-09-30 15:12:51

+1

不会'ARGV.shift'而不是'ARGV.pop'会更好吗? – nhed 2017-04-10 01:28:43

+0

nhed,是一个好主意,因为通常需要第一个或第二个位置参数,而后一个是可选的(比如'zip'你首先必须为压缩文件放置文件名,然后压缩到文件的列表存档)。 – 2017-12-27 19:31:44

0

Optparse仅使用参数AFAIK进行参数。处理文件名的“正确”方法是在optparse之外处理它。我回答this问题发布了一些示例代码。

顺便说一句,这是一个相当不寻常的命令行。如果它只是为了你,那很好,但其他人可能会发现它相反的直觉。这将是更正常的有:script.rb [options] <filename> ...

+0

谢谢,积分 – 2010-03-16 09:13:41

+0

OptParse处理各种选项。它的标志,参数,可选参数,列表,布尔值。有关更多信息,请参见[完整示例](http://ruby-doc.org/ruby-1.9/classes/OptionParser.html)。 – 2010-11-24 22:27:30

9

只是为了跟进什么Julik和Shadowfirebird说:当与OptionParser解析注意parse!parse有不同的功能。前者会将所理解的每个参数从通过的数组中移除,而后者将使其保留。这改变了你的条件,以确定是否存在所需的参数。

3

虽然这并不适用于每一种情况,它往往是很高兴能够在单个命令行上处理多个文件,如:

script.rb [options] file1 file2 ... 

文件1是强制性的,但文件2和超越是可选的。

我知道要做到这一点,最好的办法如下约定:

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中唯一剩下的东西。

1

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

如果你这样做:

rest = optparse.parse! 

你将会得到一个给定的文件/ s的阵列(沿未知选项)。这样你就不必在意这些选项是在文件之前还是之后。