shell入门学习笔记-15-命令详解: 三剑客之一awk-内置函数与自定义函数

系列目录与参考文献传送门: shell入门学习笔记-序章

awk内置函数

函数描述
int(expr)截断为整数
sqrt(expr)平方根
rand()返回一个随机数N01范围,0<N<1
srand([expr])使用expr生成随机数,如果不指定,默认使用当前时间为种子,
如果前面有种子则使用生成随机数
asort(a,b)对数组a的值进行排序,把排序后的值存到新的数组b中,
新排序的数组下标从1开始
asorti(a,b)对数组a的下标进行排序,同上
sub(r,s[,t])对输入的记录用s替换rt可选针对某字段替换,但只替换第一个字符串
gsub(r,s[,t])对输入的记录用s替换rt可选针对某字段替换,替换所有字符串
match(str, regex)测试字符串str是否包含匹配regex的字符串
index(str,sub)返回str中字符串sub的索引位置,0为不存在
length(str) length(arr)返回str的长度;返回数组arr的大小
split(str, arr,regex)根据分隔符regexstr分成数组arr
substr(s,i[,n])截取字符串si开始到长度n,如果n没指定则是剩余部分
tolower(str)str中的所有大写转换成小写
toupper(str)str中的所有小写转换成大写
systime()当前时间秒数
mktime()将格式化的时间转换成时间秒数
strftime([format[,timestamp[,utc-flag]]])格式化输出时间,将时间戳转为字符串

截取整数int(var)

admindeMacBook-Pro:myshell admin$ echo "111 11.1 11a 11a1" |awk '{for(i=1;i<=NF;i++) print $i}'
111
11.1
11a
11a1
admindeMacBook-Pro:myshell admin$ echo "111 11.1 11a 11a1" |awk '{for(i=1;i<=NF;i++) print int($i)}'
111
11
11
11
admindeMacBook-Pro:myshell admin$ echo "111 11.1 11a 11a1" |awk '{for(i=1;i<=NF;i++) print +$i}'
111
11.1
11
11
  • int(var)可以截取var中出现的第一个整数
  • int(var)截取的是整数,这个要与+var区分。

平方根sqrt(expr)

admindeMacBook-Pro:myshell admin$ awk 'BEGIN{print sqrt(9)}'
3

随机数rand()与srand()

rand()生成的值是固定不变的,取值范围:(0,1)

admindeMacBook-Pro:~ admin$ awk 'BEGIN{print rand()};'
0.840188
admindeMacBook-Pro:~ admin$ awk 'BEGIN{print rand()};'
0.840188
admindeMacBook-Pro:~ admin$ awk 'BEGIN{print rand();print rand()}'
0.840188
0.394383
admindeMacBook-Pro:~ admin$ awk 'BEGIN{print rand()};'
0.840188

rand()需要与srand()结合,才能让生成的值发送变化,可以把srand()想象成随机方法的种子发生了变化:

admindeMacBook-Pro:~ admin$ awk 'BEGIN{srand();print rand()};'
0.424539
admindeMacBook-Pro:~ admin$ awk 'BEGIN{srand();print rand()};'
0.780827

通过rand()生成1~100以内的随机数:

admindeMacBook-Pro:~ admin$ awk 'BEGIN{srand();print int(rand()*100)};'
63
admindeMacBook-Pro:~ admin$ awk 'BEGIN{srand();print int(rand()*100)};'
49

数组值排序asort(a,b)和数组下标排序asorti(a,b)

数组值排序asort(a,b)和数组下标排序asorti(a,b)都是将数组a排序之后将值放入数组b。

# 原始数组
admindeMacBook-Pro:~ admin$ echo 0 |awk 'BEGIN{a[1]="line11";a[3]="line09";a[4]="line12";a[8]="line10"}{for(v in a) print "a["v"]="a[v]}'
a[4]=line12
a[8]=line10
a[1]=line11
a[3]=line09
# asort按照值排序
admindeMacBook-Pro:~ admin$ echo 0 |awk 'BEGIN{a[1]="line11";a[3]="line09";a[4]="line12";a[8]="line10"}{N=asort(a,b);for(j=1;j<=N;j++) print "b["j"]="b[j]}'
b[1]=line09
b[2]=line10
b[3]=line11
b[4]=line12
# asorti按照下标排序
admindeMacBook-Pro:~ admin$ echo 0 |awk 'BEGIN{a[1]="line11";a[3]="line09";a[4]="line12";a[8]="line10"}{N=asorti(a,b);for(j=1;j<=N;j++) print "b["j"]="b[j]}'
b[1]=1
b[2]=3
b[3]=4
b[4]=8
  • asort排序,将结果放入数组b中,抛弃原数组下标。
  • asorti下标排序,将结果放入数组b中,抛弃原数组值。

字段替换sub(r,s[,t])和全局字段替换gsub(r,s[,t])

admindeMacBook-Pro:~ admin$ printf "1 2 3 2 5\n2 5 3 2 1\n1 3 2 1 2\n"
1 2 3 2 5
2 5 3 2 1
1 3 2 1 2
# 替换首个匹配的字段 且 不指定字段
admindeMacBook-Pro:~ admin$ printf "1 2 3 2 5\n2 5 3 2 1\n1 3 2 1 2\n" |awk '{sub(2,0);print $0}'
1 0 3 2 5
0 5 3 2 1
1 3 0 1 2
# 替换全部匹配的字段 且 不指定字段
admindeMacBook-Pro:~ admin$ printf "1 2 3 2 5\n2 5 3 2 1\n1 3 2 1 2\n" |awk '{gsub(2,0);print $0}'
1 0 3 0 5
0 5 3 0 1
1 3 0 1 0
# 替换首个匹配的字段 且 指定字段
admindeMacBook-Pro:~ admin$ printf "1 2 3 2 5\n2 5 3 2 1\n1 3 2 1 2\n" |awk '{sub(2,0,$2);print $0}'
1 0 3 2 5
2 5 3 2 1
1 3 2 1 2
# 替换全部匹配的字段 且 指定字段
admindeMacBook-Pro:~ admin$ printf "1 2 3 2 5\n2 5 3 2 1\n1 3 2 1 2\n" |awk '{gsub(2,0,$2);print $0}'
1 0 3 2 5
2 5 3 2 1
1 3 2 1 2
  • sub(r,s)只替换每行记录的第一个匹配的字段。
  • gsub(r,s)替换每行记录的全部匹配的字段。
  • sub(r,s)sub(r,s,t)的区别是,后者只尝试去匹配指定的字段。

正则匹配match(str, regex)

# 存在
admindeMacBook-Pro:~ admin$ awk 'BEGIN{print match("abc123","123")}'
4
# 不存在
admindeMacBook-Pro:~ admin$ awk 'BEGIN{print match("abc123","321")}'
0

字符串索引index(str,sub)

# 单个字符的索引
admindeMacBook-Pro:~ admin$ awk 'BEGIN{print index("hello","h")}'
1
admindeMacBook-Pro:~ admin$ awk 'BEGIN{print index("hello","e")}'
2
# 连续字符的索引
admindeMacBook-Pro:~ admin$ awk 'BEGIN{print index("hello","he")}'
1
admindeMacBook-Pro:~ admin$ awk 'BEGIN{print index("hello","el")}'
2
# 首个匹配的字符
admindeMacBook-Pro:~ admin$ awk 'BEGIN{print index("hello","l")}'
3
# 不存在时,结果为0
admindeMacBook-Pro:~ admin$ awk 'BEGIN{print index("hello","k")}'
0
  • 索引位置从1开始,0表示不存在。
  • 如果存在多个匹配,则结果只表示第一个匹配的索引。

字符串长度length([s])

admindeMacBook-Pro:~ admin$ awk 'BEGIN{a="1111";print length(a)}'
4
admindeMacBook-Pro:~ admin$ awk 'BEGIN{a[1]="1111";a[3]="2222";print length(a)}'
2
  • length(var):变量var的长度
  • length(arr):数组arr的大小

分割split(str, arr,regex)

admindeMacBook-Pro:~ admin$ awk 'BEGIN{str="10.20.30.40";split(str,arr,".");for(v in arr) print arr[v]}'
40
10
20
30
admindeMacBook-Pro:~ admin$ awk 'BEGIN{str="10.20.30.40";split(str,arr);for(v in arr) print arr[v]}'
10.20.30.40
admindeMacBook-Pro:~ admin$ awk 'BEGIN{str="10 20 30 40";split(str,arr);for(v in arr) print arr[v]}'
40
10
20
30
admindeMacBook-Pro:~ admin$ awk 'BEGIN{FS=".";str="10.20.30.40";split(str,arr);for(v in arr) print arr[v]}'
40
10
20
30
  • 如果没有指定分隔符regex,则使用FS作为分隔符。

截取字符串substr(s,i[,n])

admindeMacBook-Pro:~ admin$ awk 'BEGIN{str="123haha";print substr(str,3)}'
3haha
admindeMacBook-Pro:~ admin$ awk 'BEGIN{str="123haha";print substr(str,3,2)}'
3h
  • substr(s,i):截取字符串s,从所有i开始,直到末尾。
  • substr(s,i,n):截取字符串s,从所有i开始,截取长度为n。

大小写转换tolower(s)和toupper(s)

admindeMacBook-Pro:~ admin$ awk 'BEGIN{s="Hello World";print s;print tolower(s);print toupper(s)}'
Hello World
hello world
HELLO WORLD

系统时间systime、mktime和strftime

通过systime获取系统秒数:

admindeMacBook-Pro:~ admin$ awk 'BEGIN{print systime()}'
1551088337

通过systime("date")获取系统日期:

admindeMacBook-Pro:~ admin$ awk 'BEGIN{system("date");}'
2019年 02月 25日 星期一 17:55:39 CST

通过mktime(dataspec)"YYYY MM DD HH MM SS"格式的日期转换为时间秒数:

admindeMacBook-Pro:~ admin$ awk 'BEGIN{print systime()}'
1551088808
admindeMacBook-Pro:~ admin$ awk 'BEGIN{print mktime("2019 02 25 17 57 30")}'
1551088650

通过strftime([format [, timestamp[, utc-flag]]])对时间秒数进行格式化输出:

admindeMacBook-Pro:~ admin$ awk 'BEGIN{print strftime("%Y-%m-%d %H:%M:%S",systime())}'
2019-02-25 18:03:00
admindeMacBook-Pro:~ admin$ awk 'BEGIN{print strftime("%Y-%m-%d %H:%M:%S",mktime("2019 02 25 17 57 30"))}'
2019-02-25 17:57:30

下面是strftime能够使用的格式化字符:

SN描述
%a星期缩写(Mon-Sun)。
%A星期全称(Monday-Sunday)。
%b月份缩写(Jan)。
%B月份全称(January)。
%c本地日期与时间。
%C年份中的世纪部分,其值为年份整除100。
%d十进制日期(01-31)
%D等价于 %m/%d/%y.
%e日期,如果只有一位数字则用空格补齐
%F等价于 %Y-%m-%d,这也是 ISO 8601 标准日期格式。
%gISO8610 标准周所在的年份模除 100(00-99)。比如,1993 年 1 月 1 日属于 1992 年的第 53 周。所以,虽然它是 1993 年第 1 天,但是其 ISO8601 标准周所在年份却是 1992。同样,尽管 1973 年 12 月 31 日属于 1973 年但是它却属于 1994 年的第一周。所以 1973 年 12 月 31 日的 ISO8610 标准周所在的年是 1974 而不是 1973。
%GISO 标准周所在年份的全称。
%h等价于 %b.
%H用十进制表示的 24 小时格式的小时(00-23)
%I用十进制表示的 12 小时格式的小时(00-12)
%j一年中的第几天(001-366)
%m月份(01-12)
%M分钟数(00-59)
%n换行符 (ASCII LF)
%p十二进制表示法(AM/PM)
%r十二进制表示法的时间(等价于 %I:%M:%S %p)。
%R等价于 %H:%M。
%S时间的秒数值(00-60)
%t制表符 (tab)
%T等价于 %H:%M:%S。
%u以数字表示的星期(1-7),1 表示星期一。
%U一年中的第几个星期(第一个星期天作为第一周的开始),00-53
%V一年中的第几个星期(第一个星期一作为第一周的开始),01-53。
%w以数字表示的星期(0-6),0表示星期日 。
%W十进制表示的一年中的第几个星期(第一个星期一作为第一周的开始),00-53。
%x本地日期表示
%X本地时间表示
%y年份模除 100。
%Y十进制表示的完整年份。
%z时区,表示格式为+HHMM(例如,格式要求生成的 RFC 822或者 RFC 1036 时间头)
%Z时区名称或缩写,如果时区待定则无输出。

awk自定义函数

语法

function function_name(param1,param2,...)
{
  body
}

示例

[worker@c2-a02-126-10-4 hanchao]$ cat func.awk
# sum
function sum(a,b)
{
   return a + b;
}

# avg
function avg(a,b)
{
   return (a + b) / 2;
}

# main
function main(a,b)
{
   print "sum=",sum(a,b);
   print "avg=",avg(a,b);
}

BEGIN{
   main(10,20)
}
[worker@c2-a02-126-10-4 hanchao]$ awk -f func.awk
sum= 30
avg= 15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值