首页 > 代码库 > awk(三)函数

awk(三)函数

函数是一个独立计算的过程,它接收一些参数并返回一些值

awk有很多内置函数,分为:算术函数和字符串函数

算术函数

cos(x)返回x的余弦(x为弧度)
exp(x)
返回e的x次幂
int(x)
返回x的整数部分的值
log(x)
返回x的自然对数(以e为底)
sin(x)
返回x的正弦(x为弧度)
sqrt(x)
返回x
atan2(y,x)
返回y/x的反正切,其值在-180度到180度之间
rand()
返回随机数r,其中0<=r<1
srand(x)建立rand()的新的种子数,如果没有指定种子数目,就用当天的时间。返回旧的种子数

算术函数一共有9个,常用的也就3个。

int(x)

root@salt-master:~/sedAawk/awk# awk ‘BEGIN{print int(100/3)}‘
33

rand()和srand(x)

这两个函数经常会配合使用

楼主测试了下,rand()在gawk和mawk中,是有区别的。看个例子

lrwxrwxrwx 1 root 0 4 Mar 23  2013 /bin/awk -> gawk
[root@AY131217172003Z ~]# awk ‘BEGIN{print rand();srand();print rand()}‘
0.237788
0.145391
[root@AY131217172003Z ~]# awk ‘BEGIN{print rand();srand();print rand()}‘
0.237788
0.47599
root@salt-master:~/sedAawk/awk# ls -l /usr/bin/awk 
lrwxrwxrwx 1 root root 21 Jun 24 19:50 /usr/bin/awk -> /etc/alternatives/awk
root@salt-master:~/sedAawk/awk# ls -l /etc/alternatives/awk
lrwxrwxrwx 1 root root 13 Jun 24 19:50 /etc/alternatives/awk -> /usr/bin/mawk
root@salt-master:~/sedAawk/awk# awk ‘BEGIN{print rand();srand();print rand()}‘
0.876008
0.876008
root@salt-master:~/sedAawk/awk# awk ‘BEGIN{print rand();srand();print rand()}‘
0.270622
0.270622

注意:mawk中,默认就是用srand()之后的种子。所以rand()的返回值是变化。。。而gawk中,未执行srand()的时候,rand()的种子是不变的,所以看到前后两次未执行srand()的时候,rand()的返回值均为0.237788


字符串函数

gsub(r,s,t)在字符串t中,用字符串s替换和正则表达式r匹配的所有字符串。返回替换的个数,如果没有给出t,默认为$0。。。。在gawk中和mawk中使用,有点区别
index(s,t)
返回子串t在字符串s中的位置,如果没有指定s,则返回0
length(s)
返回字符串s的长度,当没有给出s时,返回$0的长度
match(s,r)
如果正则表达式r在s中出现,则返回出现的起始位置。如果s中未发现r,则返回0。设置RSTART和RLENGTH的值
split(s,a,sep)
使用字段分隔符sep将字符串s分解到数组a的元素中,返回元素的个数。如果没有给出sep,则使用FS。数组分隔和字段分隔采用同样的方式
sprintf("fmt",expr)
对expr使用printf格式说明
sub(r,s,t)
在字符串t中用s替换正则表达式r的首次匹配。如果成功则返回1,否则返回0,如果没有给出t,则默认为$0。。。。在gawk中和mawk中使用,有点区别
substr(s,p,n)
返回字符串s中从位置p开始,最大长度为n的子串,如果没有给出n,返回p开始的所有的字符串
tolower(s)
将字符串s中所有大写字符转换为小写,并返回新串
toupper(s)
将字符串s中所有小写字符转换为大写,并返回新串

sprintf("fmt",expr)

sprintf()和printf使用相同的格式说明,不同的地方是,printf把结果直接打印到终端。而sprintf则不会打印结果,而是可以把结果赋值给变量

看个例子

root@salt-master:~/sedAawk/awk# awk ‘BEGIN{sprintf("c",100)}‘
root@salt-master:~/sedAawk/awk# awk ‘BEGIN{a=sprintf("c",100);print a}‘
c

字串处理[index(s,t),substr(s,p,n)]

index(s,t)返回子串t在字符串s中首次出现的位置

root@salt-master:~/sedAawk/awk# awk ‘BEGIN{print index("222111","1")}‘
4

substr(s,p,n)有点类似python中的序列的切片。

注意:p开始的n个字符,是包括p位置的字符的

root@salt-master:~/sedAawk/awk# awk ‘BEGIN{print substr("asdfghj",2,3)}‘
sdf
root@salt-master:~/sedAawk/awk# awk ‘BEGIN{print substr("asdfghj",2)}‘
sdfghj

length(s)

返回字符串的长度。不指定s,则默认为$0

root@salt-master:~/sedAawk/awk# awk ‘BEGIN{print length("211212")}‘
6
root@salt-master:~/sedAawk/awk# awk ‘{print length()}‘ test
11
11

替换函数[sub(r,s,t),gsub(r,s,t)]

sub和gsub的区别,是sub只实现第一个位置的替换,而gsub则实现所有位置的替换。

注意:

1.如果没指定t,则默认为$0

2.sub和gsub返回的不是替换后的字符串,而是替换的次数。   字符串t会被改变,可以打印t得到替换后的结果

3.替换字符串中如果有&,则表示和前面的正则表达式对于。和sed中的类似

注意这两个函数在gawk中和mawk中,使用是有些区别的。gawk中可以正常使用,而mawk中则有点问题

root@salt-master:~/sedAawk/awk# awk ‘BEGIN{sub(/2/,"asd","22")}‘
awk: line 1: syntax error at or near 22
root@salt-master:~/sedAawk/awk# awk ‘BEGIN{A="22";a=gsub(/2/,"&qwer",A);print A,a}‘
2qwer2qwer 2

大小写转换[tolower(s),toupper(s)]

root@salt-master:~/sedAawk/awk# echo "HeLlo"|awk ‘{printf("<%s>,<%s>\n",tolower($0),toupper($0))}‘
<hello>,<HELLO>

match(s,r)

注意

1.match(s,r)和index(s,t),这两个函数的第一个参数为字符串,第二个参数为正则或子串。而其他的像sub(r,s,t),gsub(r,s,t)这两个函数的字符串是最后一个参数

2.match(s,r)返回首次匹配结果的位置

3.match(s,r)有两个相关的系统变量,RSTART,RLENGTH。。这两个系统变量,记录match(s,r)函数执行后的,匹配结果的起始位置,及匹配结果的长度。。。RSTART默认值为0,RLENGTH默认值为-1

match()在实际运用中,主要用于条件语句,循环,或者例程模式的条件判断。

书上有个例子,在这里套用一下

root@salt-master:~/sedAawk/awk# cat lower 
awk ‘
BEGIN {upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      lower = "abcdefghijklmnopqrstuvwxyz"
}
{
    while (match($0,/[A-Z]+/))
       for (x=RSTART;x<RSTART+RLENGTH;++x){
           CAP = substr($0,x,1)
	   CHAR = index(upper,CAP)
	   gsub(CAP,substr(lower,CHAR,1))
       }
    print $0

}‘ $*

执行

root@salt-master:~/sedAawk/awk# echo "Hello"| bash lower 
hello

自定义函数

格式:

function name(parameter-list){

    statements

    return expression

}

parameter-list是用逗号分隔的变量列表

一般函数定义在脚本顶部,所有模式操作之前

看个例子,定义一个insert函数,可以在指定的字符串的指定位置,插入指定的字符串

root@salt-master:~/sedAawk/awk# awk ‘
function insert(STRING,POS,INS) {
before_tmp = substr(STRING,1,POS)
after_tmp = substr(STRING,POS+1)
return before_tmp INS after_tmp
}
BEGIN{print insert("1234",2,"AAA")}
‘
12AAA34

awk中的自定义函数,也可以放到文件中,方面管理及重用

[root@AY131217172003Z ~]# awk  -f insert.awk -f  insert          
12AAA34

不过楼主测了下,awk的脚本不写在文件中的话,直接命令行。。好像不能用文件中的函数。

看下面的例子

[root@AY131217172003Z ~]# awk  -f insert ‘BEGIN{print insert("dfsdfsf",2,"OOOO")}‘            
[root@AY131217172003Z ~]# awk  ‘BEGIN{print insert("dfsdfsf",2,"OOOO")}‘ -f insert
awk: fatal: function `insert‘ not defined

当然,gawk还提供了一些函数。systime(),strftime(format,timestamp)等时间相关的函数。

[root@AY131217172003Z ~]# awk ‘BEGIN{print systime()}‘                    
1405488653
[root@AY131217172003Z ~]# awk ‘BEGIN{print strftime("%Y-%m-%d %H:%M:%S")}‘
2014-07-16 13:30:55

楼主的系统是Debian,默认是mawk,不支持这些时间函数





本文出自 “西风” 博客,请务必保留此出处http://lixcto.blog.51cto.com/4834175/1438972