我尝试使用[: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,为什么这段代码片段无法运行?如何修改它?
答案 0 :(得分:2)
你不能把你的图案放在大括号内。
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:]]
答案 1 :(得分:2)
Awk语法是:
<condition> { <action> }
如果<action>
对于当前记录为真,则执行<condition>
。你写的是:
{ <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个字符类和一个字符列表({{1} })。
来自POSIX(http://pubs.opengroup.org/onlinepubs/9699919799/toc.htm):
字符类表达式表示为字符类名称 括在括号内 - (“[:”和“:]”)分隔符。
和
括号表达式(用方括号括起来的表达式,“[]” )...是匹配列表表达式或不匹配列表 表达。它由一个或多个表达式组成:...,字符 课程,.....
因此,字符类为\t
,括号表达式为[:<name>:]
,其中[<expression>]
可以/包含字符类:<expression>
。
P.S。警告:有一个常用的网站http://www.regular-expressions.info/posixbrackets.html,其字符类和括号表达式的术语完全错误。或者更公平地说,他们使用的术语充其量是模糊的,因为他们将POSIX括号表达式称为“字符类”,但他们也将POSIX字符类称为“字符类”。无论你想要表征它,因为它们在自己的网站上陈述自己,它们的术语肯定不是POSIX用于括号表达式和字符类的术语