【问题标题】:How to run the find shell command with the regex option in ruby如何在 ruby​​ 中使用正则表达式选项运行 find shell 命令
【发布时间】:2015-09-07 19:42:30
【问题描述】:

我需要在 ruby​​ 脚本中使用 regex 选项运行 Linux find 命令,但它似乎不起作用。该命令所做的只是查找扩展名为 rb 或 erb 或 js 的文件。我知道命令本身很好,因为我可以在命令提示符窗口中运行它。

这是我要运行的查找命令:

find . -regex ".*\.\(rb\|erb\|js\)"

这是我的 ruby​​ 脚本的样子:

#!/usr/bin/env ruby
files = `find . -regex ".*\.\(rb\|erb\|js\)"`
puts files

我知道我可以使用 -name 选项而不是正则表达式,但看起来正则表达式应该可以工作。此外,我能够让命令 find . -regex ".*\.rb" 在我的 ruby​​ 脚本中工作。似乎括号或管道有问题?

任何建议/帮助将不胜感激。谢谢!

【问题讨论】:

  • 如果脚本中的元字符由 Ruby 处理,您可以尝试像 find . -regex ".*\.(rb|erb|js)" 一样重新转义。也许在模式末尾添加$\z 也会有所帮助。

标签: ruby regex linux shell


【解决方案1】:

stribizhev's comment 的推测是正确的:反引号中的命令文字与双引号中的字符串文字 (") 遵循相同的转义和替换/字符串插值规则。

单引号 (') 中的字符串文字按字面意思保留,因此以下内容应该可以正常工作,而无需双重转义:

#!/usr/bin/env ruby
command = 'find . -regex ".*\.\(rb\|erb\|js\)"'
files = `#{command}`
puts files 

【讨论】:

  • 显然,shell (bash 在我的例子中) 转义只修改后跟特殊字符的反斜杠序列,它不考虑点 (.) 或 piple (@987654327 @) 在一个特殊的双引号字符串中。所以它确实适用于这个特定的命令,但这只是因为我们很幸运。如果该模式在正则表达式和 bash 字符串文字中都包含一些特殊的东西,那就会出错。但是在没有 ruby​​ 的情况下在 shell 上执行的原始命令也会失败。
  • 现在这取决于正则表达式方言。对于某些方言,未转义的括号是分组的,而转义的括号是字面括号,对于方言则相反:转义的括号是分组的,而未转义的括号是字面的括号。 find 似乎使用了后一种变体(因为 Jessica 的命令可以正常工作)。
  • 太棒了 :-) 不过,请考虑 @muistooshort 的建议,使用 Ruby 的 Find 模块,而不是让它执行命令行调用。
【解决方案2】:

Ruby 有 shellescape https://apidock.com/ruby/String/shellescape,它可以让你显式地转义要传递给 Unix 样式 shell 的参数。你的例子可能写成

`find . -regex #{Shellwords.shellescape ".*\.\(rb\|erb\|js\)"}`

【讨论】:

    猜你喜欢
    • 2015-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    • 2014-07-07
    • 2015-12-20
    相关资源
    最近更新 更多