OptParse 中不带分隔符的参数列表

List of arguments in OptParse without separator

我目前正在构建一个简单的程序,它将在标准输出上读写文件。我想以这种方式启动我的程序:ruby main.rb -f file1 file2 file3 ...

但是使用 optParse 我无法让它工作我必须包括分隔符..我需要 optParse 因为我处理多个选项(比如详细,帮助......)。所以如果我这样做:ruby main.rb -f file1,file2 ...它有效

我怎样才能做到这一点?

谢谢!

如果您没有传递的选项参数,或者如果所有其他参数都是可选的,您可以通过老式的方式传递文件:通过 ARGV。默认情况下,命令行选项由 space 分隔,而不是逗号。

如果您绝对需要支持 -f 选项,您可以另外添加对 ARGV 的支持

require "optparse"

options = {
  :files => []
}
opt_parse = OptionParser.new do |opts|
  opts.banner = "Usage: main.rb file(s) ..."

  opts.on("-f", "--files file1,file2,...", Array, "File(s)") do |f|
    options[:files] += f
  end

  opts.on_tail("-h", "--help", "Show this message") do
    puts opts
    exit
  end

end
opt_parse.parse!

options[:files] += ARGV

if options[:files].length == 0
  abort(opt_parse.help)
end

puts options[:files]

使用此方法,您甚至可以混合两种样式:

$ main.rb -f -f file1,file2 file3 -f file4 file5
file1
file2
file4
file3
file5

(注意 file5 实际上是通过 ARGV 传递的,但看起来您正在使用 space 作为分隔符。)

有几种方法可以使用 optparse 接受给定参数的多个值。有些方法允许使用 space 分隔的列表,但每种方法都有其优点和缺点。好消息是这些方法可以互换使用,因此您始终可以实现多种方法并让最终用户使用他们喜欢的方法。

给定一个名为 process_files.rb 的脚本,如下所示:

require 'optparse'

args = { files: [] }

OptionParser.new do |opts|
  # Option 1: use an array-type optparse argument
  opts.on('--files FILE1,FILE2,...', Array, 'A list of comma-separated files.') do |files|
    args[:files].concat(files)
  end

  # Option 2: use a single-value argument; expect it to be repeated multiple times
  opts.on('-f', '--file FILE', 'A single file. Repeat for multiple files.') do |file|
    args[:files] << file
  end

  # Option 3: take a string and split it using whatever delimiter you want
  opts.on('--colon-files FILE1:FILE2:...', 'A colon-delimited file list.') do |str|
    args[:files].concat(str.split(':'))
  end

  # Option 4: as above, but quoting the file list on the command line allows space delimiting
  opts.on('--spaced-files "FILE1 FILE2 ..."', 'A space-delimited file list.') do |str|
    args[:files].concat(str.split(/\s+/))
  end
end.parse!

# Option 5: Assume all remaining, unparsed arguments are whitespace-delimited files
args[:files].concat(ARGV)

puts args[:files].inspect

以下是向其提供文件列表的各种方法:

$ ruby process_files.rb --files foo,bar,baz
["foo", "bar", "baz"]

$ ruby process_files.rb -f foo -f bar -f baz
["foo", "bar", "baz"]

$ ruby process_files.rb --colon-files foo:bar:baz
["foo", "bar", "baz"]

$ ruby process_files.rb --spaced-files 'foo bar baz'
["foo", "bar", "baz"]

$ ruby process_files.rb foo bar baz
["foo", "bar", "baz"]

$ ruby process_files.rb --files apple,banana -f cherry --colon-files date:elderberry \
    --spaced-files 'fig grape' honeydew
["apple", "banana", "cherry", "date", "elderberry", "fig", "grape", "honeydew"]

参考:https://rubyreferences.github.io/rubyref/stdlib/cli/optparse.html