使用 Ruby optparse 处理文件列表

Using Ruby optparse to process list of files

是否可以使用 Ruby 的 OptionParser 处理文件列表,或者 ARGV 是否必须单独解析?

我正在尝试为 Linux 中的 Ruby 脚本 运行 解析命令行参数。目前我的脚本是使用如下样式调用的:./run.rb /dir/* 我解析 ARGV 以获取它所操作的文件列表。但是,现在我有几个要切换的操作,所以我不想编辑脚本,而是想添加一个命令行选项。因此脚本将被调用为 ./run.rb -a action -i /dir/*.

当我试图让它工作时,我 运行 遇到问题,只获取目录中的第一个文件。 “Parsing command-line arguments as wildcards”解释说,原因是 shell 正在扩展文件列表,并且当 OptionParser 处理数组时,它会查找逗号分隔值。答案还说:

Because the * wildcard gets replaced with space delimited filenames you'll have to post-process ARGV after OptionParser has run against it, or programmatically glob the directory and build the list that way. ARGV has all the files except the one picked up in the -a option so, personally, I'd drop the -a option and let ARGV contain all the files.

OptionParser 无法处理由 shell 扩展返回的 space 分隔值,这是否正确?我还没有找到任何东西,所以我认为我的解释是正确的。但我也认为这将是一个常用的功能,所以我很惊讶是这种情况,这就是这个问题的原因。

考虑您的脚本,但使用相反的选项调用:

./run.rb -i /dir/* -a action

假设 /dir/ 包含两个文件,foobar,这将由 shell 扩展为:

./run.rb -i /dir/bar /dir/foo -a action

脚本如何区分以下内容?

  1. 两个文件被指定为 -i 选项的值和 -a 选项被指定为 action 的值(预期情况),和

  2. 四个 文件被指定为 -i 操作的值(/dir/bar/dir/foo 和以前一样,加上 -aaction)

做到这一点的唯一方法是坚持 -i 选项始终放在最后,这样就没有其他选项了,在这种情况下,您不妨完全取消该选项并执行答案你引用建议。

请记住,shell 执行通配符(和其他)扩展,然后在空格上拆分命令以创建字符串数组,并在 before 执行此操作你的脚本可以看到它,所以这个问题更多地与 shell 有关而不是 OptionParser (同样的问题会影响任何语言的任何选项解析库)。我想将文件列表作为 选项 传递给命令(而不是主要输入)还不足以保证改变 shell 行为或添加功能以不同的方式扩展(至少我不知道有任何这样的替代扩展)。

视情况而定。像这样传递参数时可以忽略文件扩展

--list=Desktop/tour/*

在这种情况下,您可以自己 Dir.glob 文件。

另一方面,OptionParser 具有处理参数列表的能力:

opts.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
  options[:list] = list
end

您可以将所有这些与其他答案结合起来,或者查看高级解析器,例如 trollop