awk 使用正则表达式
在awk中,正则表达式(regex)允许动态和复杂的模式定义。 您不仅限于搜索简单的字符串,而且还搜索模式中的模式。
使用正则表达式匹配awk中的行的语法为:
word ~ / match /
相反的是不匹配模式:
word ! ~ / match /
如果您还没有的话,请根据我们上一篇文章创建示例文件:
name color amount
apple red 4
banana yellow 6
strawberry red 3
raspberry red 99
grape purple 10
apple green 8
plum purple 2
kiwi brown 4
potato brown 9
pineapple yellow 5
将文件另存为colours.txt并运行:
$
awk
-e
'$1 ~ /p[el]/ {print $0}' colours.txt
apple
red
4
grape purple
10
apple green
8
plum purple
2
pineapple yellow
5
您选择含有字母p,然后无论是 电子或L的所有记录。
在方括号内添加o会创建一个新样式以匹配:
$
awk
-e
'$1 ~ /p[o]/ {print $0}' colours.txt
apple
red
4
grape purple
10
apple green
8
plum purple
2
pineapple yellow
5
potato brown
9
正则表达式基础
某些字符在正则表达式中使用时具有特殊含义。
锚点
锚 | 功能 |
---|---|
^ | 指示行的开头 |
$ | 指示行尾 |
\A | 表示字符串的开头 |
\z | 表示字符串的结尾 |
\b | 标记单词边界 |
例如,此awk命令将打印包含r字符的任何记录:
$
awk
-e
'$1 ~ /r/ {print $0}' colours.txt
strawberry
red
3
raspberry
red
99
grape purple
10
添加一个^符号以仅选择在行首出现r的记录:
$
awk
-e
'$1 ~ /^r/ {print $0}' colours.txt
raspberry
red
99
性格
字符 | 功能 |
---|---|
[ad] | 选择a或d |
[a-d] | 选择任意字符a到d (a,b,c或d) |
[^a-d] | 选择除 a到d (e,f,g,h…) 之外 的任何字符 |
\w | 选择任何单词 |
\s | 选择任何空白字符 |
\d | 选择任意数字 |
w,s和d的大写形式为负数; 例如, \ D 不选择任何数字。
POSIX正则表达式为字符类提供了简单的助记符:
POSIX助记符 | 功能 |
---|---|
[:alnum:] | 字母数字字符 |
[:alpha:] | 字母字符 |
[:space:] | 空格字符(例如空格,制表符和换页符) |
[:blank:] | 空格和制表符 |
[:upper:] | 大写字母字符 |
[:lower:] | 小写字母字符 |
[:digit:] | 数字字符 |
[:xdigit:] | 十六进制数字字符 |
[:punct:] | 标点符号(即不是字母,数字,控制字符或空格字符的字符) |
[:cntrl:] | 控制字符 |
[:graph:] | 既可打印又可见的字符(例如,空格是可打印但不可见的,而a则是两个) |
[:print:] | 可打印字符(即不是控制字符的字符) |
量词
量词 | 功能 |
---|---|
. | 匹配任何字符 |
+ | 将前面的集合修改为一次或多次 |
* | 将前面的集合修改为零次或多次 |
? | 将前面的集合修改为零或一次 |
{n} | 将前面的集合修改为准确地表示n次 |
{n,} | 将前面的集合修改为n次或多次 |
{n,m} | 将前面的集合修改为n到m次之间的平均值 |
许多量词会修改其前面的字符集。 例如, 。 表示仅出现一次的任何字符,但是。*表示任何或没有字符。 这是一个例子。 仔细看一下正则表达式模式:
$
printf
"red \n rd \n "
red
rd
$
printf
"red \n rd \n "
|
awk
-e
'$0 ~ /^r.d/ {print}'
red
$
printf
"red \n rd \n "
|
awk
-e
'$0 ~ /^r.*d/ {print}'
red
rd
同样,括号中的数字指定发生某事的次数。 要查找其中e字符恰好出现两次的记录:
$
awk
-e
'$2 ~ /e{2}/ {print $0}' colours.txt
apple green
8
分组比赛
量词 | 功能 |
---|---|
(red) | 括号表示必须将相邻的字母连续显示 |
| | 均值或在分组匹配的上下文中 |
例如,模式(red)与单词red和ordered匹配,但与包含所有其他三个字母的另一个单词(例如单词order )匹配的单词都不匹配。
像sed一样用sub()和gsub()
Awk具有执行查找和替换操作的多个功能,非常类似于Unix命令sed 。 这些函数就像print和printf一样 ,并且可以在awk规则中用于用新字符串替换字符串,无论新字符串是字符串还是变量。
子函数用替换字符串替换(记录中的) 第一个匹配的实体。 例如,如果在awk脚本中具有以下规则:
{ sub
(
/ apple
/ ,
"nut" ,
$1
) ;
print
$1
}
在示例文件colours.txt上运行它会产生以下输出:
name
nut
banana
raspberry
strawberry
grape
nut
plum
kiwi
potato
pinenut
苹果和菠萝都被坚果代替的原因是两者都是他们的记录的第一个匹配项。 如果记录不同,那么结果可能会不同:
$
printf
"apple apple \n pineapple apple \n "
| \
awk
-e
'sub(/apple/, "nut")'
nut apple
pinenut apple
gsub命令替换所有匹配项:
$
printf
"apple apple \n pineapple apple \n "
| \
awk
-e
'gsub(/apple/, "nut")'
nut nut
pinenut nut
Gensub
这些函数的甚至更复杂的版本也称为gensub() 。
gensub功能允许您使用&字符来调用匹配的文本。 例如,如果您有一个带有单词Awk的文件,并且想要将其更改为GNU Awk ,则可以使用以下规则:
{ print gensub ( / ( Awk ) / , "GNU &" , 1 ) }
这将搜索字符组Awk并将其存储在内存中,并由特殊字符&表示 。 然后,它将字符串替换为GNU& ,表示GNU Awk 。 最后的1字符告诉gensub()替换第一个匹配项。
$
printf
"Awk \n Awk is not Awkward" \
|
awk
-e
' { print gensub(/(Awk)/, "GNU &",1) }'
GNU Awk
GNU Awk is not Awkward
有时间和地方
Awk是一个功能强大的工具,而正则表达式很复杂。 您可能会认为awk如此强大,以至于可以轻松替换grep和sed以及tr和sort等,在某种意义上,您是对的。 但是,awk只是工具箱中充斥着众多选项的一种工具。 您可以选择使用什么工具以及何时使用它,因此不必觉得无论大小任务都需要使用一种工具。
话虽如此,awk确实是一个功能强大且功能强大的工具。 使用的次数越多,您越了解它。 记住它的功能,并偶尔使用它,这样您就可以适应它。
我们的下一篇文章将介绍Awk中的循环,所以很快回来!
本文改编自社区技术播客Hacker Public Radio 。
翻译自: https://opensource.com/article/19/11/how-regular-expressions-awk
awk 使用正则表达式