Grep - 如何仅输出捕获组的内容

Sam*_*ami 13 bash shell grep

我试图找到一种方法让 grep 只输出捕获组的内容。例如,如果我有以下文件:

hello1, please match me
hello2, please do not match me
Run Code Online (Sandbox Code Playgroud)

我想

hello1, please match me
hello2, please do not match me
Run Code Online (Sandbox Code Playgroud)

输出hello1. 但是它输出hello1, please match me.

现在,我知道这grep -Po 'hello[0-9]+(?=, please match me)'可以解决问题,但我认为必须有一种方法可以简单地返回一个捕获组,但是我找不到任何信息(在网络上和 中man grep)。

是否有可能,或者捕获组仅用于反向引用?如果没有办法做到这一点,我会觉得很奇怪。

感谢您的时间,并随时批评这篇文章的构建方式!

小智 41

您可以使用ripgrep,它通常似乎优于 grep ,如下所示

rg '(hello[0-9]+), please match me' -or '$1' <file>
Run Code Online (Sandbox Code Playgroud)

其中 ripgrep 使用-oor--only matching-ror--replace仅输出第一个捕获组$1(引用以避免 shell 解释为变量)。


Ame*_*hel 8

这个问题是十年前问的,所以我不会将其标记为重复。我还注意到没有给出 sed 解决方案,因为 OP 没有给出答案:

sed -nr 's/(hello[0-9]+), please match me/\1/p' test.txt
Run Code Online (Sandbox Code Playgroud)
  • -n 代表安静(除非明确要求,否则不会打印任何内容)
  • -r允许使用扩展正则表达式(避免\在括号前使用)
  • s/reg/repl/p命令的意思是“如果正则表达式reg匹配当前行,用捕获的文本替换它repl,并打印它(/p)”

  • 现在又回到了原点,因为 `g/re/p` 的意思是“全局搜索正则表达式并打印” (2认同)

ric*_*ici 6

如果您有,pcregrep或者pcre2grep您可以使用-o1命令行标志来请求只输出捕获组 1。(或者,如果正则表达式中有更多捕获,则将 1 更改为其他数字。)

如果要输出多个捕获组,可以多次使用该命令。-oN

据我所知,grep -P没有实现这个扩展。您将pcre2grep在 Debian/Ubuntu 包中找到pcre2-utilspcregrep在包中pcregrep


Rog*_*ahl 6

grepsed并且awk拥有不支持任何现代正则表达式功能的古老正则表达式引擎。我真的认为它们不再适合目的了。

有一件事Perl仍然很好,那就是作为几乎所有单行代码的替代品,因为它有一个非常好的、现代的正则表达式引擎,以及一些方便的命令行开关,-ne并且-pe.

这些开关使 Perl 自动将表达式应用到输入的每一行,并无条件打印结果,或者让您控制结果的打印。

例如,要打印后面hello跟着数字 ( hello\d) 的所有行的hello\d第一个please match me,您可以执行以下操作:

perl -ne 'm/(hello\d) please match me/ && print "$1\n"' <file>
Run Code Online (Sandbox Code Playgroud)

有许多不错的网站列出了您可以使用 Perl 单行代码完成的常见任务,例如这个

我还认为ripgrep应该出现在每个人的工具箱中。


Jot*_*tne 5

只是一个awk版本。

awk -F, '/hello[0-9]+, please match me/ {print $1}' file
hello1
Run Code Online (Sandbox Code Playgroud)

  • @SlippD.Thompson 它会输出 之前的所有内容,如果它有数字 hello,请匹配我。您可以使用 `awk -F, '/, please match me/ {print $1}' file` 来获取“please match me”前面的任何内容 (3认同)
  • 我不确定我是否理解如何使用它——我在你的正则表达式中没有看到捕获组。 (2认同)