3

我有一长串要过滤的生成报告。报告是这样的:

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

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

我已经搜索了 SX 并发现这些不起作用:

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

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

更新

正如@WiktorStribiżew 指出的那样,该 ag 使用 PCRE。对不起这个错误。

我的预期输出是:

blah blah: WORD2

或者只是匹配文件的列表。


ps目前我已经设法使用这个:

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

4 回答 4

4

您可以使用 PCRE 模式ag

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

请参阅正则表达式演示

详情

  • (?s)- 一个 DOTALL 修饰符(.匹配换行符)
  • ^- 字符串的开始
  • (?=.*WORD1) - 字符串中必须有WORD1某处
  • (?=.*WORD2)- 字符串中必须有WORD2某处
  • .*- 任何 0+ 字符,尽可能多,直到后续子模式的最后一次出现(如果您使用惰性*?量词,.*?将尽可能少地匹配 0+ 字符,直到后续子模式的第一次出现)
  • \n- 换行符
  • \K- 匹配重置运算符丢弃当前匹配的文本
  • (?-s)- 禁用 DOTALL 模式(.不匹配换行符)
  • .*WORD2- 除换行符以外的任何 0+ 个字符,尽可能多,然后WORD2.
于 2017-06-26T06:51:04.943 回答
2

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

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

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

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

这会在匹配的两侧给出三行并突出显示WORD1WORD2

于 2018-09-23T19:58:35.840 回答
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 hello 和所有文件中的世界

于 2020-12-16T03:07:39.780 回答
0

ps目前我已经设法使用这个: ag "WORD2" $(ag -l "WORD1")

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

如果你使用 ack,它有一个-x操作符,可以让你做这与无需引入管道ack -l WORD1 | ack -x WORD2基本相同的事情。ack -l WORD1 | xargs ack WORD2xargs

于 2017-06-27T03:21:02.533 回答