awk函数使用总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CPP_MAYIBO/article/details/84107445

 

目录

算术函数

字符串函数

输入输出函数

时间函数

位操作函数

其他函数

自定义函数


awk用许多内置函数,包括算术函数、字符串函数、输入输出函数、时间函数、位操作函数等,awk也支持自定义函数。

算术函数

函数

功能

atan2(y, x)

返回 y/x 的反正切,其值在-π到π之间

cos(x)

返回 x 的余弦

sin(x)

返回 x 的正弦

exp(x)

返回 e 的 x 次幂

log(x)

返回 x 的以 e 为底自然对数

sqrt(x)

返回 x 平方根

int(x)

返回 x 的整数部分的值

rand()

返回任意数字 n,其中 0 <= n < 1

srand([x])

将 rand 函数的种子值设置为 X 参数的值,或如果省略 X 参数则使用当天的时间;返回先前的种子值

# awk '
BEGIN { print atan2(0,-1)
  print exp(1)
  print 100/3
  print int(100/3)
  print rand()
  print rand()
  srand()
  print rand()
  print rand()
} '
3.14159
2.71828
33.3333
33
0.237788
0.291066
0.503071
0.44804

示例1:指定范围内随机数的生成

传递一个参数,输出一个改参数范围内的一个随机整数

# vim lotto1.sh
awk -v TOPNUM=$1 '
 BEGIN {
    srand()
    select = 1 + int(rand() * TOPNUM)
    print select
}'

执行结果如下:

# sh lotto1.sh 123
117
# sh lotto1.sh 123
51
# sh lotto1.sh 123
97

示例2:指定范围内生成指定个数的随机数

传递2个参数,第一个参数生成的个数,第二个是随机数的范围

# cat lotto2.sh 
awk -v NUM=$1 -v TOPNUM=$2 '
BEGIN {
if (NUM<=0)
   NUM=6
if (TOPNUM<=0)
  TOPNUM=30
 
  printf("Pick %d of %d\n",NUM,TOPNUM)
  srand()
  for(j=1;j<=NUM;j++){
    do{
      select=1+int(rand()*TOPNUM)
    }while(select in pick)
    pick[select]=select
  }
 
  for(j in pick)
    printf("%s ",pick[j])
  printf("\n")
}'

执行结果如下:

# sh lotto2.sh 5 89
Pick 5 of 89
35 47 31 1 42 
# sh lotto2.sh 3 189
Pick 3 of 189
73 169 145 

字符串函数

函数

功能

asort(source [, dest [, how ] ]) 

按照value值对source数组进行排序,同时会将数组的index值替换为数字,数字是以1开始排序,该方法返回source的元素个数

asorti(source [, dest [, how ] ])

和asort类似,只是排序是按照source的index值进行排序

gensub(regexp, replacement, how [, target])

用replacement替换由regexp在目标字符串target中匹配出的字符串,how指定替换匹配出的第几个字符串,如果how是'g'或'G'开头的字符串,表示替换所有匹配出的字符串;如果不指定target,则使用$0;该方法返回替换后的字符串

gsub(regexp, replacement [, target])

功能基本同gensub,只是没有how参数,也就是gsub会替换所有匹配出的字符串;该方法返回替换的字符串个数

index(in, find)

在find字符串中查找in字符串,返回in第一次出现的位置

length([string])

返回字符串的长度,如果没有指定string,默认使用$0

match(string, regexp [, array])

在string中匹配regexp,如果匹配成功返回匹配的位置,否则返回0;这个方法会修改系统变量RSTART和RLENGTH的值,其中RSTART是匹配字符串的起始位置,RLENGTH是匹配字符串的长度

patsplit(string, array [, fieldpat [, seps ] ])

 

split(string, array [, fieldsep [, seps ] ])

切分字符串string,将切分的字符串放入到array中,fieldsep指定分隔符,如果不指定分隔符使用FS的值,seps用以存储array[i]与array[i+1]之间的分隔符;该方法返回array的元素个数

sprintf(format, expression1, ...)

返回printf以相同参数打印出的字符串。

strtonum(str)

检查str并返回它的十进制数值,如果str以0开头,则将str看做8进制数,如果string以‘0x’或‘0X’开头,则将str看做十六进制数

sub(regexp, replacement [, target])

功能和gsub类似,但是sub只替换匹配到的第一个字符串,其返回值是0(没有匹配到)或者1

substr(string, start [, length ])

返回从string中获取从start开始长度为length的子串,如果不指定length,则获取从start到string末尾的子串

tolower(string)

将string中大写字母转换为小写并返回新串

toupper(string)

将string中小写字母转换为大写并返回新串

示例

asort()、asorti()

# gawk 'BEGIN{
> a["last"]="de"
> a["first"]="sac"
> a["middle"]="cul"
> asort(a)
> for(i in a)
>   print "a["i"] = " a[i]
> }'
a[1] = cul
a[2] = de
a[3] = sac
 
# gawk 'BEGIN{
> a["last"]="de"
> a["first"]="sac"
> a["middle"]="cul"
> asorti(a)
> for(i in a)
>   print "a["i"] = " a[i]
> }'
a[1] = first
a[2] = last
a[3] = middle

上述例子中asort方法只有一个参数,程序它就会修改数组a的内容,如果有两个参数,它会将source数组排序的结果写入到dest数组中,如下:

# gawk 'BEGIN{
> a["last"]="de"
> a["first"]="sac"
> a["middle"]="cul"
> asort(a,b)
> for(i in a)
>   print "a["i"] = " a[i]
> print "-----------"
> for(i in b)
>   print "b["i"] = " b[i]
> }'
a[first] = sac
a[middle] = cul
a[last] = de
-----------
b[1] = cul
b[2] = de
b[3] = sac

gensub() 、 gsub() 、sub()

# gawk 'BEGIN{
> a = "Hello World"
> b = gensub(/(.+) (.+)/, "\\2 \\1", "g", a)
> print b
> }'
World Hello
 
# echo a b c a b c a b c |  gawk '{ print gensub(/a/, "hadoop", 2) }'
a b c hadoop b c a b c
 
# echo a b c a b c a b c |  gawk '{ print gensub(/a/, "hadoop", "ggg") }'
hadoop b c hadoop b c hadoop b c
 
# echo a b c a b c a b c | gawk '{ gsub(/a/, "hadoop") ;print}'
hadoop b c hadoop b c hadoop b c
 
# echo a b c a b c a b c | gawk '{ sub(/a/, "hadoop") ;print}'
hadoop b c a b c a b c

从上面的例子中可以看出gensub对替换的控制粒度是最强的。

下面看一个有意思的示例:

# awk 'BEGIN {
> str = "daabaaa"
> sub(/a+/, "C&C", str)
> print str
> }'
dCaaCbaaa
 
# awk 'BEGIN {
str = "daabaaa"
gsub(/a+/, "C&C", str)    
print str
}'
dCaaCbCaaaC

仔细看上面的示例,发现在第二参数有个字符 &,该字符用以表示需要在第一个参数中指定的字符串。

index()

# awk 'BEGIN { print index("peanut", "an") }'
3

length()

# awk 'BEGIN { print length("peanut") }'
6
# awk 'BEGIN { print length(25*5) }'
3

上面例子中,有个计算25*5字符串的长度,首先会计算25*5的结果,是125,然后将125转换为字符串“125”,再计算器长度。结果是3

match()

假设字段中有多个冒号“:”,现在需要将第二冒号替换为中横线 "-":

下面分别是输入文件内容和脚本内容:

# cat test1
1234:2134:::hello
4341:45::09:world
 
# cat test1.awk
match($1,/:[^:]*:/){
     before=substr($1,1,(RSTART+RLENGTH-2))
     after=substr($1,(RSTART+RLENGTH))
     $1=before "-" after
     print $1
}

执行结果如下:

# awk -f test1.awk test1
1234:2134-::hello
4341:45-:09:world

split()

# awk 'BEGIN {
> str = "cul-de-sac"
> split(str,a,"-",seps)
> for(i in a) 
>   print "a["i"] = " a[i]
> for(i in seps)
>   print "seps["i"] = " seps[i]
> }'
a[1] = cul
a[2] = de
a[3] = sac
seps[1] = -
seps[2] = -

sprintf()

# awk 'BEGIN {
> pival = sprintf("pi = %.2f (approx.)", 22/7)
> print pival
> }'
pi = 3.14 (approx.)

strtonum()

# echo 0x11 | gawk '{ printf "%d\n", strtonum($1) }'
17
# echo 0123 | gawk '{ printf "%d\n", strtonum($1) }'
83
# echo abc | gawk '{ printf "%d\n", strtonum($1) }'
0

substr()

# awk 'BEGIN {
print substr("707-555-1111",6)
print substr("707-555-1111",6,2)
}'
55-1111
55

 tolower(),toupper()

# cat user
user1 78 98 90 84
user2 89 75 47 99
user3 74 83 92 78
 
# awk '{printf("<%s>,<%s>\n",tolower($0),toupper($0))}' user
<user1 78 98 90 84>,<USER1 78 98 90 84>
<user2 89 75 47 99>,<USER2 89 75 47 99>
<user3 74 83 92 78>,<USER3 74 83 92 78>

输入输出函数

system()函数

system()函数执行一个以表达式方式给出的命令。然而,它的命令没有产生可供程序处理的输出。它返回被执行命令的退出状态。

如下示例,创建一个目录,第一次会执行成功,第二次执行失败:

# awk '
> BEGIN {
>  if(system("mkdir dir")!=0)
>     print "Command Failed"
> }'
# ls dir
# awk '
BEGIN {
 if(system("mkdir dir")!=0)
    print "Command Failed"
}'
mkdir: cannot create directory ‘dir’: File exists
Command Failed

 

时间函数

函数

功能

mktime(datespec [, utc-flag ])

用于将时间字符串转换为时间戳格式,参数datespec的格式是 "YYYY MM DD HH MM SS [DST]",如果给定格式不正确或者缺少信息,将会返回-1

strftime([format [, timestamp [, utc-flag] ] ])

用于将时间戳转换为指定格式的时间字符串,参数format默认值是"%a %b %e %H:%M:%S %Z %Y",格式和命令 date 的默认输出是一样的

systime()

返回从1970年1月1日开始到当前时间(不计闰年)的整秒数

示例

mktime(datespec [, utc-flag ])

# gawk 'BEGIN{print mktime("2018 10 25 12 34 23")}'
1540442063
#  gawk 'BEGIN{print mktime("2018 10 25 12 34 ")}'
-1
# gawk 'BEGIN{print mktime("2018-10-25 12:34:23")}'
-1

strftime([format [, timestamp [, utc-flag] ] ])

# gawk 'BEGIN{print strftime()}'
Thu Nov 15 10:38:03 CST 2018
# gawk 'BEGIN{print strftime("%Y-%m-%d %H:%M:%S")}'
2018-11-15 11:16:11

systime()

# gawk 'BEGIN{print systime()}'
1542249087

位操作函数

函数

功能

and(v1, v2 [, ...])

返回与值

compl(val)

返回val的位补

lshift(val, count)

返回val左移count位后的值

or(v1, v2 [, ...])

返回或值

rshift(val, count)

返回val右移count位后的值

xor(v1, v2 [, ...])

返回异或值

示例

# gawk 'BEGIN{print compl(12)}'
9007199254740979
# gawk 'BEGIN{print and(12,0)}'
0
# gawk 'BEGIN{print or(12,0)}'
12
# gawk 'BEGIN{print rshift(12,1)}'
6
# gawk 'BEGIN{print lshift(12,1)}'
24
# gawk 'BEGIN{print xor(12,0)}'
12
# gawk 'BEGIN{print xor(12,12)}'
0

其他函数

isarray(x) : 判断x是否是一个数组,是返回1,否则返回0

示例

# awk 'BEGIN {
str = "cul-de-sac"
split(str,a,"-",seps)
print isarray(str)
}'
0
# awk 'BEGIN {
str = "cul-de-sac"
split(str,a,"-",seps)
print isarray(a)  
}'
1

自定义函数

自定义函数的语法定义如下:

function name([parameter-list])
{
body-of-function
}

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

示例

function insert(string,pos,ins){
before_tmp=substr(string,1,pos)
after_tmp=substr(string,pos+1)
return before_tmp ins after_tmp
}

上面函数insert有三个参数,函数的功能是在字符串string的pos配置插入另一个字符串ins。执行如下:

# vim test2.awk 
function insert(string,pos,ins){
before_tmp=substr(string,1,pos)
after_tmp=substr(string,pos+1)
return before_tmp ins after_tmp
}
 
match($1,/:[^:]*:/){
     $1=insert($1,RSTART+RLENGTH+1,"XXXX")
     print $1
}
 
# awk -f test2.awk test1
1234:2134:::XXXXhello
4341:45::0XXXX9:world

需要说明的是在函数体中定义的变量默认为全局变量。对于上面的insert()函数,临时变量before_tmp和after_tmp在函数外是可见的,如下:

# vim test2.awk 
function insert(string,pos,ins){
before_tmp=substr(string,1,pos)
after_tmp=substr(string,pos+1)
return before_tmp ins after_tmp
}
 
match($1,/:[^:]*:/){
     $1=insert($1,RSTART+RLENGTH+1,"XXXX")
     print before_tmp
     print after_tmp
     print $1
}
 
# awk -f test2.awk test1
1234:2134:::
hello
1234:2134:::XXXXhello
4341:45::0
9:world
4341:45::0XXXX9:world

上述程序在主程序中打印了insert函数中的临时变量,可见临时变量在函数外部也是可见的。为了解决这个问题,可以将临时变量放在参数列表的末尾。如果想使得上面insert函数中的before_tmp和after_tmp变为局部变量,可以按照如下定义insert函数:

function insert(string,pos,ins,before_tmp,after_tmp){
before_tmp=substr(string,1,pos)
after_tmp=substr(string,pos+1)
return before_tmp ins after_tmp
}

猜你喜欢

转载自blog.csdn.net/CPP_MAYIBO/article/details/84107445
今日推荐