awk 语法是:
<condition> { <action> }
如果<condition> 对当前记录为真,则执行<action>。你写的是:
{ <condition> { <action> } }
看到区别了吗?您可以将条件放在操作块中,但是您需要用适当的控制关键字将其包围,例如 if 或 while,这样 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):
字符类表达式表示为字符类名
括在括号内 - ( "[:" 和 ":]" ) 分隔符。
和
括号表达式(用方括号括起来的表达式,“[]”
) ... 要么是匹配的列表表达式,要么是不匹配的列表
表达。它由一个或多个表达式组成:...,字符
类,.....
所以一个字符类是[:<name>:],一个括号表达式是[<expression>],其中<expression>可以是/包含一个字符类:[[:<name>:]]。
附:警告:有一个普遍引用的网站http://www.regular-expressions.info/posixbrackets.html,其中字符类和括号表达式的术语完全错误。或者更公平地说,他们使用的术语充其量是模糊的,因为他们将 POSIX 括号表达式称为“字符类”,但他们也将 POSIX 字符类称为“字符类”。但是,您想对其进行表征,正如他们在其网站上声明的那样,他们的术语肯定与 POSIX 用于括号表达式和字符类的术语不同