2010-03-15 31 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的陣列(沿未知選項)。這樣你就不必在意這些選項是在文件之前還是之後。