如何使用ag或rg匹配包含word1和word2的所有文件到不同的行(PCRE / Rust regex)

时间:2017-06-26 06:07:38

标签: regex regex-lookarounds ag

我想要过滤生成的报告列表。报告是这样的:

Report Name
Report Date
Blah blah blah
Blah: WORD1
Blah blah
blah blah: WORD2
blah blah

我正在尝试使用ag(PCRE regex)或rg(rust regex)并在文件的不同位置查找包含WORD1和WORD2的所有文件(包含新行)。

我已经搜索过SX,发现这些不起作用:

> ag (?=.*WORD1)(?=.*WORD2)

> ag (?=.*WORD1)((.|\n)*)(?=.*WORD2)

更新

正如@WiktorStribiżew所指出的那样,ag使用了PCRE。抱歉这个错误。

我的预期输出是:

blah blah: WORD2

或只是匹配文件列表。

P.S。目前我已经成功使用了这个:

> ag "WORD2" $(ag -l "WORD1")

4 个答案:

答案 0 :(得分:3)

您可以使用ag的PCRE模式:

(?s)^(?=.*WORD1)(?=.*WORD2).*\n\K(?-s).*WORD2

请参阅regex demo

<强>详情:

  • (?s) - DOTALL修饰符ON(.匹配换行符)
  • ^ - 字符串开头
  • (?=.*WORD1) - 字符串中必须有WORD1
  • (?=.*WORD2) - 字符串中必须有WORD2
  • .* - 尽可能多的任何0+字符,直到后续子模式的最后一次出现(如果使用惰性*?量词,.*?将匹配0+尽可能少的字符,直到后续子模式的第一次次出现)
  • \n - 换行符
  • \K - 匹配重置运算符,丢弃当前匹配的文本
  • (?-s) - DOTALL模式已停用(.与换行符不匹配)
  • .*WORD2 - 除了换行符之外的任何0 +字符,尽可能多,然后WORD2

答案 1 :(得分:1)

问题提到了这种模式,该模式有效:

ag "WORD2" $(ag -l "WORD1")

但是只有WORD2会突出显示颜色。我更喜欢:

ag 'WORD1|WORD2' --passthru -C3 $(ag -l "WORD1" $(ag -l "WORD2"))

这会在比赛的两边给出三行,并突出显示WORD1WORD2

答案 2 :(得分:1)

function agmw() {
  args=("$@")
  qs="ag -l  $1"
  for i in {2..$#}; do
    qs="$qs | xargs -r ag -l '${args[$i]}'"
  done
  argarr="$1"
  for i in {2..$#}; do
    argarr="$argarr|${args[$i]}"
  done
  qs="$qs | xargs -r ag '$argarr'"
  echo $qs
  ag '$argarr'
  bash -c $qs
}

agmw hello world#seacrh和所有文件中的世界

答案 3 :(得分:0)

  

P.S。目前我已设法使用此功能:ag "WORD2" $(ag -l "WORD1")

这当然是最简单的方法。您正在谈论的工具本质上是面向行的,您正在寻找匹配同一文件中不同行的工具。

如果你使用ack,它有-x运算符,可以让ack -l WORD1 | ack -x WORD2ack -l WORD1 | xargs ack WORD2基本相同,而不必将xargs引入管道