终于在“使用 ruby 的 OptionParser 解析子命令”中找到了解决方案。
我需要使用记录不佳的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