函数是一个独立计算的过程,它接收一些参数并返回一些值
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,不支持这些时间函数