【问题标题】:Escaping regex in a Ruby awk system command在 Ruby awk 系统命令中转义正则表达式
【发布时间】:2018-06-22 11:20:17
【问题描述】:

以下内容直接在我的 Mac OS X 终端中运行,创建一个包含几行的文件:

awk '!/^1499\||^1598\||^1599\||^1999\||^2298\||^2299\||^2403\|/' "#{working_path}" > "#{filtered_file_path}"

但是,当我尝试使用反引号在 Ruby on Rails 中使用它时,结果文件为空:

`awk '!/^1499\||^1598\||^1599\||^1999\||^2298\||^2299\||^2403\|/' "#{working_path}" > "#{filtered_file_path}"`

带有简单正则表达式的 awk 可以工作。例如:

`awk '!/SMITH/' "#{working_path}" > "#{filtered_file_path}"`

因此,问题似乎与转义的管道字符有关。

想法?


我应该提供一些背景:

我正在处理的文件是用竖线分隔的。我正在过滤掉具有某些代码的行,这些代码位于该行的第一个值中。所以,我使用的正则表达式类似于^2298\|

表达式中单引号中的其他管道是正则表达式 OR 运算符。

“working_path”和“filtered_file_path”是 Ruby 变量。

【问题讨论】:

  • 不应该是/^1499\|^1598\|^1599\|^...吗?我有点惊讶这在 cmd 行中有效。正则表达式“OR”用一个 | 字符完成。布尔逻辑由两个 (||) 完成。如果您只使用 | 会发生什么?祝你好运。
  • 为什么不直接在 ruby​​ 中进行过滤?
  • @shelter 好问题。我本可以提供更多细节。我正在处理的文件是一个以竖线分隔的文件,因此我在第一列中搜索某些代码(例如 1499|)。反斜杠转义文字管道字符,下一个管道字符是 OR 运算符。
  • @TomFenech 另一个好问题。感谢您为对话做出贡献。简单的答案是速度。这是一个 230 万行的文件,我必须对其进行多次操作。除了 awk,我还在上面运行 sort 和 comm。以 Linux 命令的形式执行这些操作使它们完成的速度比在 Ruby 中快一个数量级。我喜欢 Ruby 的许多方面,但处理大型文本文件可能比人们希望的要慢。

标签: ruby-on-rails ruby regex awk


【解决方案1】:

我刚刚想通了。转义管道字符的反斜杠也需要转义。不知道为什么常规终端和 Ruby 之间存在差异,但确实存在。工作版本:

`awk '!/^1499\\||^1598\\||^1599\\||^1999\\||^2298\\||^2299\\||^2403\\|/' "#{working_path}" > "#{filtered_file_path}"`

在挑战了我认为问题出在 Ruby on Rails 的假设之后,这里接受的答案就是解释它的原因: Pipe symbol | in AWK field delimiter

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    • 2015-05-03
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    相关资源
    最近更新 更多