官方解释:
The awk function split(s,a,sep) splits a string s into an awk array a using the delimiter sep.
awk的功能拆分(s,a,sep)分割字符串s转换为使用的分隔符sep的一个a的awk数组
举例说明
[root@cloudmas home]# cat rz.log
14:36:10[root@cloudmas home]#cat rz.log | awk '{split($0,a,":" ); print a[1]}' # 输出 14
[root@cloudmas home]#cat rz.log | awk '{split($0,a,":" ); print a[3]}' # 输出10
[root@cloudmas home]#cat rz.log | awk '{split($0,a,":" ); print a[1], a[2], a[3]}' #输出 14:36:10
实现需求:现需统计客户当天每小时短信发送量。
具体情况如下:从短信发送服务器中统计出2023年12月08日当天每小时短信发送量,当天日志存放/data/log/sender01.log,格式如下
[root@cloudmas home]# cat /data/log/sender01.log|more -10
2023-12-08 14:36:04,281 INFO [com.wcjy.core.cmpp.CmppWork:473] cid[11] send Submit: sequence_id = 3,dest_terminal_id[0] = 1441539672078
2023-12-08 14:36:04,288 INFO [com.wcjy.core.cmpp.CmppWork:473] cid[11] send Submit: sequence_id = 4,dest_terminal_id[0] = 1441539672080
使用AWK split函数统计每小时短信发送量
zgrep "send Submit: sequence_id" /data/apache-send01/log/sender01.log | awk -F "," '{split($1,a," "); split(a[2],b,":"); hour=b[1]; if(hour~/^[0-9]+$/ && hour>=0 && hour<=23) {count[hour]++}} END {for (hour in count) printf("%02d:00-%02d:59\t%d\n",hour,hour,count[hour])}'
输出结果:
[root@cloudmas apache-send01]# zgrep "send Submit: sequence_id" /data/apache-send01/log/sender01.log | awk -F "," '{split($1,a," "); split(a[2],b,":"); hour=b[1]; if(hour~/^[0-9]+$/ && hour>=0 && hour<=23) {count[hour]++}} END {for (hour in count) printf("%02d:00-%02d:59\t%d\n",hour,hour,count[hour])}'
08:00-08:59 361500
02:00-02:59 421800
03:00-03:59 430200
04:00-04:59 428400
05:00-05:59 428400
14:00-14:59 172301
06:00-06:59 430415
15:00-15:59 126000
07:00-07:59 429985
以上这是一个使用 awk 结合split的实际应用,根据一个以逗号分隔的日志文件sender01.log 中的时间戳,统计每个小时的访问次数,并将结果以表格形式输出。具体的解释如下:
1. 运行 zgrep "send Submit: sequence_id" /data/apache-send01/log/sender01.log ,将/sender01.log 中的内容作为输入;
2. 通过管道将输入传递给 awk 命令;
3. 在 awk 中,-F "," 指定逗号为分隔符,在每行中根据逗号将其分成多个字段;
4. split($1,a," ") 将第一个字段(时间戳)根据空格分割成两个部分,存储到数组 a 中;
5. split(a[2],b,":") 将 a 数组中第二个元素(时间)根据冒号分割成三个部分,存储到数组 b 中;
6. hour=b[1] 将小时数存储到变量 hour 中;
7. if(hour~/^[0-9]+$/ && hour>=0 && hour<=23) 判断变量 hour 是否为数字且处于 0~23 范围内;注意:符号用于进行正则表达式匹配,/^[0-9]+$/
表示匹配一个或多个数字,即判断变量 hour
是否为纯数字。 &&
符号用于连接多个条件,表示多个条件同时满足时才成立。 >=
和 <=
符号分别表示大于等于和小于等于,用于判断变量 hour
是否在 0~23 的范围内;
8. count[hour]++ 统计每个小时的访问次数,使用数组 count 存储;
9. END 块在处理完整个文件后执行,遍历 count 数组中存储的计数值并将其格式化为表格形式输出;
10. 输出的格式为 "%02d:00-%02d:59\t%d",其中 %02d 表示两位数的十进制数,\t 表示制表符,\n 表示换行符。
注意:printf
函数中,%02d:00-%02d:59\t%d\n
是一个格式化字符串,它需要三个参数来替换占位符(其中包含两个 %02d
占位符和一个 %d
占位符)。
在这里,第一个 %02d
占位符需要被替换为一个表示小时数的整数(即 hour
变量),第二个 %02d
占位符同样需要被替换为一个表示小时数的整数(这也是为什么要传入两个 hour
变量)。最后一个 %d
占位符需要被替换为计算出来的当前小时数的日志数量(即 count[hour]
变量的值)。
因此,在这个 printf
函数中需要传入两个 hour
变量,以便分别替换前面两个 %02d
格式化占位符。