【问题标题】:grep regexp to match space and/or TAB and '[:space:]' classgrep 正则表达式匹配空格和/或 TAB 和 '[:space:]' 类
【发布时间】:2020-12-17 19:25:06
【问题描述】:

在 CentOS 8 上,这个 grep 表达式不返回匹配的字符串:

% dmidecode -t memory | grep -E '^[ \t]+Size: [0-9]+'

但是这个确实返回了匹配的行(在同一个发行版上):

% dmidecode -t memory | grep -E '^[[:space:]]+Size: [0-9]+'

这种行为的原因是什么?如您所见,grep 两次都在扩展正则表达式模式下被调用。

【问题讨论】:

  • grep '^[ \t]+Size: [0-9]+' 中,模式被解析为 POSIX BRE。如果您希望将 + 解析为量词,请传递 -E 标志以使其成为 POSIX ERE。
  • 您在第一个 grep 命令中缺少 -E
  • 发布问题时,我在第一个命令中错过了'-E',它应该在那里,仍然 grep 它不返回匹配的行。
  • 那么你需要grep -E '^[[:blank:]]+Size: [0-9]+'grep -E '^[[:blank:]]+Size:[[:blank:]]+[0-9]+'。请注意,[ \t] 作为正则表达式模式实际上等同于 [:blank:] POSIX 字符类,而不是 [:space:](它也包括纯空格)。
  • @WiktorStribiżew 不,这是正则表达式。第一个只是不像 OP 认为的那样工作。

标签: linux grep centos


【解决方案1】:

这里的问题是\t 字符序列。这确实匹配grep 正则表达式中的制表符,它匹配字符t(不管它是基本方言还是扩展方言RE)。它不像其他一些工具那样被视为特殊的转义序列(包括使用 PCRE 方言的 GNU grep)。

证人:

# printf /does/ treat \t and \n special in a format
$ printf "a\tb\n" | grep "a[ \t]b" # No match
$ printf  "atb\n" | grep "a[ \t]b" # Match
atb
$ printf "a\tb\n" | grep "a[[:space:]]b" # Match
a     b
$ printf "a\tb\n" | grep "a[[:blank:]]b" # Match
a     b
$ printf "a\tb\n" | grep "a\sb" # Match, \s is a GNU grep extension
a     b
$ printf "a\tb\n" | grep -P "a\sb" # Match, GNU grep using PCRE
a     b
$ printf "a\tb\n" | grep -P "a[ \t]b" # Match, GNU grep using PCRE.
a     b

【讨论】:

    【解决方案2】:

    使用匹配空格字符和制表符字符的[[:blank:]]。你也可以省略-E

    grep '^[[:blank:]]+ Size: [0-9]+'
    

    【讨论】:

    • 您的解决方案does not work。 OP 的解决方案适用于 -E 选项。在 POSIX BRE 中,+ 匹配加号。
    • 需要 ^[[:blank:]]\{1,\} Size: [0-9]\{1,\} 才能在 BRE 中获得相同的效果。
    猜你喜欢
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-09
    相关资源
    最近更新 更多