目录
一、awk工具
1、awk工具简介
awk是功能强大的编辑工具,在无交互的情况下实现复杂的文本操作。它是专门为文本处理设计的编程语言,也是处理软件,通常用于扫描、过滤、统计汇总工作,数据可以来自标准输入也可以是管道或文件。
2、awk的格式
awk 选项 '模式或条件{操作}'文件1文件2...
awk -f 脚本文件 文件1 文件2...
格式 :awk关键字 选项 命令部分 '{XXXXX}' 文件名
3、awk 工作原理
当读取到第一行时,匹配条件,然后执行指定动作,再接着读取第二行数据处理,不会默认输出,如果没有定义匹配条件默认是匹配所有数据行,awk隐含循环,条件匹配多少次动作就会执行第三次
逐行读取文本,默认以空格为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令
sed命令常用于一整行的处理,而awk比较、倾向于将一行分成多个''"字段然后进行处理。awk信息的读入也是逐行读取的,执行结果可以通过print的功能将字段数据打印显示。在使用awk命令的过程中,可以使用逻辑操作符" &&表示“与” || "、"表示或 "!"表示非";还可以进行简单的数学运算,如+、-、*、/、%、^、分别表示加减乘除、取余和乘方。
4、awk内置变量
FS:指定每行文本的字段分隔符,缺省为空格或制表位
NF:当前处理的行的字段个数
NR:当前处理的行的行号(序数)
$0:当前处理的行的整行内容
$n:当前处理行的第n个字段(第n列)
FILENAME:被处理的文件名
二、awk案例
1、示例1:awk案例
三、筛选给定时间范围内的日志
grep/sed/awk用正则去筛选日志时,如果要精确到小时、分钟、秒,则非常难以实现。
但是awk提供了mktime()函数,它可以将时间转换成epoch时间值。
root@Ubuntu:~# # 2019-11-10 03:42:40转换成epoch为1970-01-01 00:00:00
root@Ubuntu:~# awk 'BEGIN{print mktime("2023 08 05 08 44 40")}'
1691196280
借此,可以取得日志中的时间字符串部分,再将它们的年、月、日、时、分、秒都取出来,然后放入mktime()构建成对应的epoch值。因为epoch值是数值,所以可以比较大小,从而决定时间的大小。
下面strptime1()实现的是将2023-08-04-12-40-40 29T03:42:40+08:00格式的字符串转换成epoch值,然后和which_time比较大小即可筛选出精确到秒的日志。
可以利用patsplit来取时间中的数字
root@Ubuntu:~# vim demo.awk
root@Ubuntu:~# cat demo.awk
BEGIN{
#要筛选什么时间的日志,将其时间构建成epoch值
which_time = mktime("2023 08 04 22 40 29")
}
{
#取出日志的日期时间字符串部分
#match($0,"^.*\\[(.*)\\].*",arr)
#将日期时间字符串转换为epoch值
tmp_time = strptime1(arr[1])
#通过比较epoch值来比较时间大小
if(tmp_time > wgich_time){print}
}
#构建的时间字符串格式为:“2023-08-04T12:40:40+08:00"
function strptime1(str ,arr,Y,M,D,H,m,S){
patsplit(str,arr,"[0-9]{1,4}")
Y=arr[1]
M=arr[2]
D=arr[3]
H=arr[4]
m=arr[5]
S=srr[6]
return mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))
}
下面strptime2()实现的是将10/Nov/2023:23:53:44+08:00格式的字符串转换成epoch值,然后和which_time比较大小即可筛选出精确到秒的日志。
root@Ubuntu:~# vim dwmo.awk
root@Ubuntu:~# cat dwmo.awk
BEGIN{
# 要筛选什么时间的日志,将其时间构建成epoch值
which_time = mktime("2023 08 04 11 42 40")
}
{
# 取出日志中的日期时间字符串部分
match($0,"^.*\\[(.*)\\].*",arr)
# 将日期时间字符串转换为epoch值
tmp_time = strptime2(arr[1])
# 通过比较epoch值来比较时间大小
if(tmp_time > which_time){
print
}
}
# 构建的时间字符串格式为:"10/Nov/2023:23:53:44+08:00"
function strptime2(str,dt_str,arr,Y,M,D,H,m,S) {
dt_str = gensub("[/:+]"," ","g",str)
# dt_sr = "10 Nov 2023 23 53 44 08 00"
split(dt_str,arr," ")
Y=arr[3]
M=mon_map(arr[2])
D=arr[1]
H=arr[4]
m=arr[5]
S=arr[6]
return mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))
}
function mon_map(str,mons){
mons["Jan"]=1
mons["Feb"]=2
mons["Mar"]=3
mons["Apr"]=4
mons["May"]=5
mons["Jun"]=6
mons["Jul"]=7
mons["Aug"]=8
mons["Sep"]=9
mons["Oct"]=10
mons["Nov"]=11
mons["Dec"]=12
return mons[str]
}