如何使用Ruby的optparse解析一个没有名称的参数?

时间:2022-10-12 23:21:49

I need to parse a command line like

我需要像这样解析命令行

  script.rb <mandatory filename> [options]

with optparse.

optparse。

Sure I can write some custom code to handle the filename, then pass ARGV to optparse, but maybe there's a simpler way to do it?

当然,我可以编写一些自定义代码来处理文件名,然后将ARGV传递给optparse,但是也许有一种更简单的方法可以做到这一点?

EDIT: there's another hacky way to parse such a command line, and that is pass ['--mandatory-filename'] + ARGV to optparse, then handle the --mandatory-filename option.

编辑:还有另一种解析命令行的简单方法,那就是将['- mandatore -filename'] + ARGV传递给optparse,然后处理——mandatore -filename选项。

5 个解决方案

#1


38  

First parse! with optparse, then scan the ARGV and raise if ARGV is empty. Like so:

第一个解析!使用optparse,然后扫描ARGV,如果ARGV是空的,就升高。像这样:

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

The mandatory filename will not be processed by the OptionParser and will be left for you in ARGV - if it's not there, just raise manually.

强制的文件名将不会被OptionParser处理,并且将在ARGV中留给您——如果它不在那里,只需手动提高。

#2


9  

Just to follow up on what Julik and Shadowfirebird said: When parsing with OptionParser be aware that parse! and parse have different functionality. The former will remove every argument it understands out of the passed array where the latter will leave them be. This changes your conditions for determining if the required argument is present.

继续胡克和Shadowfirebird所说的:在使用OptionParser进行解析时,请注意解析!解析有不同的功能。前者将从所传递的数组中删除它所理解的所有参数,后者将保留这些参数。这改变了确定所需参数是否存在的条件。

#3


3  

Although it doesn't apply to every situation, it is often nice to be able to process multiple files on a single command line, such as:

尽管它并不适用于所有情况,但是能够在单个命令行上处理多个文件(例如:

script.rb [options] file1 file2 ...

file1 is mandatory, but file2 and beyond is optional.

file1是强制性的,但file2和其他内容是可选的。

The best way I know to do this follows this convention:

我所知道的做到这一点的最好方法是遵循这个惯例:

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

If files are not provided, a help message will be displayed with the usage banner and a description of options. If the files are present, they will be the only thing left in ARGV.

如果没有提供文件,将显示一条帮助消息,并显示usage banner和选项描述。如果文件存在,它们将是ARGV中惟一剩下的文件。

#4


1  

I am not sure if it was added recently, but none of the previous answers mention that optparse.parse will return the ARGV value after removing the parsed options.

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

If you do this:

如果你这样做:

rest = optparse.parse!

You will get an array with the given file/s (along unknown options). This way you do not have to care if the options come before or after the file.

您将获得一个具有给定文件/s(以及未知选项)的数组。这样,您不必关心选项是在文件之前还是之后。

#5


0  

Optparse only does arguments with parameters, AFAIK. The "correct" way to handle your filename is to deal with it outside of optparse. I posted some example code for this in answer to this question.

Optparse只有带参数的参数,AFAIK。处理文件名的“正确”方法是在optparse之外处理它。为了回答这个问题,我发布了一些示例代码。

BTW, that's a rather unusual commandline. If it's just for you, fine, but others are likely to find it rather counter-intuitive. It would be more normal to have: script.rb [options] <filename>...

顺便说一句,这是一个很不寻常的命令行。如果只是为了你自己,那很好,但其他人可能会发现这与直觉相反。更正常的做法是:脚本。rb[选项] <文件名> …

#1


38  

First parse! with optparse, then scan the ARGV and raise if ARGV is empty. Like so:

第一个解析!使用optparse,然后扫描ARGV,如果ARGV是空的,就升高。像这样:

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

The mandatory filename will not be processed by the OptionParser and will be left for you in ARGV - if it's not there, just raise manually.

强制的文件名将不会被OptionParser处理,并且将在ARGV中留给您——如果它不在那里,只需手动提高。

#2


9  

Just to follow up on what Julik and Shadowfirebird said: When parsing with OptionParser be aware that parse! and parse have different functionality. The former will remove every argument it understands out of the passed array where the latter will leave them be. This changes your conditions for determining if the required argument is present.

继续胡克和Shadowfirebird所说的:在使用OptionParser进行解析时,请注意解析!解析有不同的功能。前者将从所传递的数组中删除它所理解的所有参数,后者将保留这些参数。这改变了确定所需参数是否存在的条件。

#3


3  

Although it doesn't apply to every situation, it is often nice to be able to process multiple files on a single command line, such as:

尽管它并不适用于所有情况,但是能够在单个命令行上处理多个文件(例如:

script.rb [options] file1 file2 ...

file1 is mandatory, but file2 and beyond is optional.

file1是强制性的,但file2和其他内容是可选的。

The best way I know to do this follows this convention:

我所知道的做到这一点的最好方法是遵循这个惯例:

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

If files are not provided, a help message will be displayed with the usage banner and a description of options. If the files are present, they will be the only thing left in ARGV.

如果没有提供文件,将显示一条帮助消息,并显示usage banner和选项描述。如果文件存在,它们将是ARGV中惟一剩下的文件。

#4


1  

I am not sure if it was added recently, but none of the previous answers mention that optparse.parse will return the ARGV value after removing the parsed options.

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

If you do this:

如果你这样做:

rest = optparse.parse!

You will get an array with the given file/s (along unknown options). This way you do not have to care if the options come before or after the file.

您将获得一个具有给定文件/s(以及未知选项)的数组。这样,您不必关心选项是在文件之前还是之后。

#5


0  

Optparse only does arguments with parameters, AFAIK. The "correct" way to handle your filename is to deal with it outside of optparse. I posted some example code for this in answer to this question.

Optparse只有带参数的参数,AFAIK。处理文件名的“正确”方法是在optparse之外处理它。为了回答这个问题,我发布了一些示例代码。

BTW, that's a rather unusual commandline. If it's just for you, fine, but others are likely to find it rather counter-intuitive. It would be more normal to have: script.rb [options] <filename>...

顺便说一句,这是一个很不寻常的命令行。如果只是为了你自己,那很好,但其他人可能会发现这与直觉相反。更正常的做法是:脚本。rb[选项] <文件名> …