【问题标题】:awk reg expression pattern matching doesn't workawk 正则表达式模式匹配不起作用
【发布时间】:2015-07-26 15:24:23
【问题描述】:

我尝试使用[:digit:] 来匹配行中的数字,这是代码。

~ echo -e "abc\n123\ndef" | awk '{/[[:digit:]]/{print $0}}'
awk: syntax error at source line 1
 context is
     >>> {/[[:digit:]]/{ <<<
awk: illegal statement at source line 1
awk: illegal statement at source line 1

我的问题是:

1、为什么要用[[:digit:]]而不是[:digit:]

2,为什么这段代码sn-p不会运行?怎么修改?

【问题讨论】:

    标签: regex shell awk


    【解决方案1】:

    你不能把你的模式放在大括号里。

    awk '/[[:digit:]]/{print $0}'
    

    语法是,

     awk 'condition{execute if the condition is true}'
    

    在某些情况下,仅条件就足够了。对于这种情况,以下就足够了,

    awk '/[[:digit:]]/'
    

    示例:

    $ echo -e "abc\n123\ndef" | awk '/[[:digit:]]/'
    123
    

    为什么使用[[:digit:]] 而不是[:digit:]

    POSIX 括号表达式 [:digit:] 单独不会匹配数字字符,您必须将其放在像 [[:digit:]] 这样的字符类中。

    如果你想匹配数字以及+ 符号,那么你可以修改上面的 POSIX 类

    [+[:digit:]]
    

    【讨论】:

    • [:digit:] 是一个“POSIX 括号表达式”,应该在字符类中使用。我不会称其为“无效”。
    • @EdMorton 我认为你只是错了。 [:digit:], [:punct:] POSIX 符号。我们需要将它们放在一个字符类中,以使其工作。 [[:digit:][:punct:]]
    • @EdMorton:我只是引用regular-expressions.info,我不是这个术语的所有者。
    • 似乎我还没有说服你正确的术语,所以我只是发布了我自己的答案,OP可以弄清楚。
    【解决方案2】:

    awk 语法是:

    <condition> { <action> }
    

    如果&lt;condition&gt; 对当前记录为真,则执行&lt;action&gt;。你写的是:

    { <condition> { <action> } }
    

    看到区别了吗?您可以将条件放在操作块中,但是您需要用适当的控制关键字将其包围,例如 ifwhile,这样 awk 就会知道您想对该条件做什么:

    { if (<condition>) { <action> } }
    { while (<condition>) { <action> } }
    

    所以,而不是:

    {/[[:digit:]]/{print $0}}
    

    为了在句法和惯用语上正确,您应该这样写:

    /[[:digit:]]/{print $0}
    

    但由于打印 $0 是默认操作,您真正要编写的是:

    /[[:digit:]]/
    

    即:

    $ echo -e "abc\n123\ndef" | awk '/[[:digit:]]/'
    123
    

    至于为什么[[:digit:]]而不是[:digit:]

    [:digit:] 是一个 POSIX 字符类,因此可以在括号表达式中用作正则表达式的一部分,例如[[:digit:]],就像范围表达式 (0-9) 或字符列表 (0123456789) 一样,也可以在括号表达式中使用以达到相同的效果。

    这个例子可能有助于澄清:[:digit:] 是一个字符类,[:punct:] 也是,所以[[:digit:][:punct:] \t] 是一个包含 2 个字符类和一个字符列表 (\t) 的括号表达式。

    来自 POSIX (http://pubs.opengroup.org/onlinepubs/9699919799/toc.htm):

    字符类表达式表示为字符类名 括在括号内 - ( "[:" 和 ":]" ) 分隔符。

    括号表达式(用方括号括起来的表达式,“[]” ) ... 要么是匹配的列表表达式,要么是不匹配的列表 表达。它由一个或多个表达式组成:...,字符 类,.....

    所以一个字符类是[:&lt;name&gt;:],一个括号表达式是[&lt;expression&gt;],其中&lt;expression&gt;可以是/包含一个字符类:[[:&lt;name&gt;:]]

    附:警告:有一个普遍引用的网站http://www.regular-expressions.info/posixbrackets.html,其中字符类和括号表达式的术语完全错误。或者更公平地说,他们使用的术语充其量是模糊的,因为他们将 POSIX 括号表达式称为“字符类”,但他们也将 POSIX 字符类称为“字符类”。但是,您想对其进行表征,正如他们在其网站上声明的那样,他们的术语肯定与 POSIX 用于括号表达式和字符类的术语不同

    【讨论】:

      猜你喜欢
      • 2014-09-15
      • 2023-01-22
      • 2017-11-13
      • 2015-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-11
      • 1970-01-01
      相关资源
      最近更新 更多