在Linux awk语言中,提供了很多有意义的函数。例如:
gsub(r,s) 在整个$0中用s代替r
gsub(r,s,t) 在整个t上用s代替r
length(s) 返回s的长度
index(s,t) 返回s中字符串t的第一位置
match(s,r) 测试s是否包含r 子串
spilt(s,a,fs) 用fs(某种分割符号)去拆分s串,将拆分后的数组赋给a
sub(r,s) 用$0中最左边最长的子串去代替s
substr(s,p) 返回字符串s从p开始的后缀部分
substr(s,p,n) 返回字符串s从p开始的长度为n的串
现在分别举例子来看这些具体的应用:
1:gsub
下面一个例子将匹配chenwu串的行替换成yangliu(注意这里要加引号,不然awk会把它当作变量)
[chenwu@localhost unit9-awkIntroduce]$ cat -n grade.txt
1 chenwu 05/99 4811 27
2 mary 02/22 1231 30
3 tom 09/15 1182 25
[chenwu@localhost unit9-awkIntroduce]$ awk 'gsub(/chenwu/,"yangliu") {print $0}' grade.txt
yangliu 05/99 4811 27
2:index(获取ny串在Bonny的起始位置,注意这里的计数与一般的编程语言不同,这里从1开始计数)
[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {print index("Bonny","ny")}' grade.txt
4
3:length
[chenwu@localhost unit9-awkIntroduce]$ awk '{if($1=="chenwu") print $1,length($1)}' grade.txt
chenwu 6
4:match
match用来匹配子串(也可以是一个正则表达式 )在父串的位置,如果匹配成功,则返回匹配的位置,否则返回0,例如:
[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {print match("ABCD",/C/)}'
3
[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {print match("ABCD",/U/)}'
0
5:split
[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {print split("123#45#22",myarray,"#")}'
3
6:substr(s,p[,n]) 返回s串中从p开始的后缀部分,n是一个可选参数,表示取多大的长度
例如
[chenwu@localhost unit9-awkIntroduce]$ awk 'BEGIN {base="I love money"} {print substr(base,3,6)}' grade.txt
love m
love m
love m
awk的这些函数在和shell的管道符结合在一起的时候,可以发挥很大的作用。例如:
返回一个目录下所有文件的句点的前缀名称。(不好使)
[chenwu@localhost unit9-awkIntroduce]$ ls -l | awk 'BEGIN {if($1!~/^d/) n=index($8,".")}
{if($1!~/^d/) print n,substr($8,n)}'
0
0 grade.report
0 grade.txt
[chenwu@localhost unit9-awkIntroduce]$ ls -l
总计 12
-rw-rw-r-- 1 chenwu chenwu 53 06-10 10:16 grade.report
-rw-rw-r-- 1 chenwu chenwu 64 06-11 10:12 grade.txt
drwxrwxr-x 2 chenwu chenwu 4096 06-11 10:28 testDir
这里为什么不好使尼?理由是n在begin里定义了后,之后就不会再变了,稍微改造后,就好使了:
[chenwu@localhost unit9-awkIntroduce]$ ls -l | awk '{n=index($8,".")} {if($1!~/^d/) print substr($8,1,n-1)}'
grade
grade
但是这里还是有点瑕疵,你会发现并没有过滤普通目录。grade的上方仍然有输出(空白)
一种较合理的解释是普通目录的确过滤掉了,但是ls -l最上方的总计12 没有过滤到,导致也对它取了次从1到句点.结束的子串,从而打印了空白。