【问题标题】:How to grep the second number only in one line?如何仅在一行中grep第二个数字?
【发布时间】:2016-01-26 15:14:42
【问题描述】:

给定test.txt的内容如下:

Hello 10 love 20 haha 30
Hello Hello 11 love love 21 haha 31
41 Hello Hello 42 love love 43 haha 44

我想要某种grep 表达式,以便在说之后:

$ cat test.txt | grep ???

我得到这个输出:

20
21
42

如何实现这个功能?

【问题讨论】:

  • “the second instance”的意思是“第二个数字”,抱歉我的表述不清楚。

标签: regex linux bash shell unix


【解决方案1】:

好像你正在尝试获取第二个数字..

grep -oP '^\D*\d+\D*\K\d+' file

使用 sed。

sed 's/^[^[:digit:]]*[[:digit:]]\+[^[:digit:]]*\([[:digit:]]\+\).*/\1/' file

DEMO

【讨论】:

  • 请注意,-P 不适用于 BSD grep。还不如只使用 Perl。 (呃,没注意到 linux 标签。没关系。)
  • BSD sed 也无法识别\1。这就是为什么跨平台解决方案(即 perl)更胜一筹的原因......
  • 你可以在 perl 中使用相同的正则表达式,perl -pe 's/^\D*\d+\D*(\d+).*/$1/' file
  • 是的,这就是我所指的。
  • @4ae1e1 看不懂\+ 但你可以用\{1,\} 代替,不需要使用标志。 perl 也只在很多情况下兼容,前提是您使用相同的版本,并且在您安装 perl 的情况下,您可以轻松安装更新的 sed/grep。无论哪种方式,对于这么简单的事情可能都不会产生太大影响。
【解决方案2】:

您可能想考虑使用 awk 的替代方法:

awk -F'[^[:digit:]]+' '{ print /^[[:digit:]]/ ? $2 : $3 }' file

这会将字段分隔符设置为一个或多个非数字字符,这意味着您感兴趣的字段是第二个或第三个字段,具体取决于该行是否以数字开头。

为简洁起见,您可能更喜欢使用范围 [0-9] 而不是 [[:digit:]]

awk -F'[^0-9]+' '{ print /^[0-9]/ ? $2 : $3 }' file

或者您可以使用 perl 来捕获您感兴趣的部分:

perl -lne 'print $1 if /\d\D+(\d+)/' file

\d 匹配数字,\D 匹配非数字,因此这会捕获在该行中找到的第二组数字。如果找不到第二组数字,则不会打印任何内容(这与 awk 脚本的行为不同)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    • 2014-08-23
    • 2018-04-04
    • 1970-01-01
    相关资源
    最近更新 更多