如何使用OptionParser为每个位置参数使用不同的选项

时间:2017-03-20 13:32:12

标签: ruby command-line-interface optionparser

我想用这种语法调用脚本:

script.rb [common-options] arg1 [arg1-options] [arg2 [arg2-options] …]

例如:

script.rb --verbose --dry-run a1 --outfile c1 a2 --reprocess --outfile c2 a3 a4 --outfile b42

将这样的内容返回给我的代码:

options = {verbose: true, :'dry-run' => true}
args = {
  'a1' => {outfile: 'c1'},
  'a2' => {outfile: 'c2', reprocess: true}, 
  'a3' => {},
  'a4' => {outfile: 'b42'},
}

我无法从OptionParser documentation中了解它是否可能。

有没有人知道这方面的解决方案?

1 个答案:

答案 0 :(得分:0)

最后在“Using ruby's OptionParser to parse sub-commands”中找到了解决方案。

我需要使用记录不良的order方法,该方法只解析第一个位置参数的选项。 parse将解析整个ARGV:

require 'optparse'

options = {}
filenames = []
file_options = Hash.new do |hash, key| hash[key] = {} end
filename = nil

file_parser = OptionParser.new do |o|
  o.banner = 'Options for every file (goes after every filename):'
  o.on '-o', '--outfile=FILE', 'A file to write result to' do |arg|
    file_options[filename][:outfile] = arg
  end
end

global_parser = OptionParser.new do |o|
  o.banner = [
    "Super duper file processor.\n",
    "Usage: #{$PROGRAM_NAME} [options] file1 [file1-options] [file2 [file2-options] …]",
  ].join("\n")
  o.separator ''
  o.separator 'Common options:'
  o.on '-v', '--verbose', 'Display result filenames' do |arg|
    options[:verbose] = arg
  end
  o.on '-h', '--help', 'Print this help and exit' do
    $stderr.puts opts
    exit
  end
  o.separator ''
  o.separator file_parser.help
end

begin
  argv = global_parser.order(ARGV)
  while (filename = argv.shift)
    filenames.push(filename)
    file_parser.order!(argv)
  end
rescue OptionParser::MissingArgument => e
  $stderr.puts e.message
  $stderr.puts global_parser
  exit 1
end

if filenames.empty?
  $stderr.puts global_parser
  exit 1
end

如果我像这样执行我的脚本:

script.rb -v a -o a.out b c d -o d.out

我会得到:

options      = {:verbose=>true}
file_options = {"a"=>{:outfile=>"a.out"}, "d"=>{:outfile=>"d.out"}}

将生成此帮助文本:

Super duper file processor.

Usage: script.rb [options] file1 [file1-options] [file [file2-options]…]

Common options:
    -v, --verbose                    Display converted filenames
    -h, --help                       Print this help and exit

Options for every file (goes after every filename):
    -o, --outfile=FILE               A file to write result to