目录
概念
AWK
AWK是一种编程语言,主要用于在Linux/Unix下对文本和数据进行处理。它支持用户自定义函数和动态正则表达式等先进功能,是Linux/Unix下的一个强大编程工具。AWK可以在命令行中使用,但更多是作为脚本来使用。AWK有3个不同版本:AWK、Nawk和Gawk,未作特别说明,一般指Gawk。
时间戳
时间戳是用来表示时间的数字化信息,通常以秒或毫秒为单位。它与具体的时间单位(如年、月、日、小时、分钟和秒)无关,只是一种计算机可以识别的数字表示方式。时间戳通常用于记录事件发生的顺序,因为它们可以精确到毫秒级别。
时间戳的起始点通常是某个特定的时间点,如UNIX时间戳的起始点是1970年1月1日00:00:00 UTC。对于UNIX时间戳,它表示从1970年1月1日00:00:00 UTC起经过的秒数。
时间戳的应用非常广泛,例如在日志文件中记录事件发生的时间,在数据库中记录数据的创建、修改或访问时间,以及在通信系统中同步时间等。通过时间戳,我们可以方便地追踪事件发生的顺序,计算时间间隔,或者对数据进行时间排序等操作。
筛选给定时间范围内的日志
首先考虑的就是把时间转换成一个时间戳,再和目前的时间做一个比较,这样才能筛选出我想要的某个时间之前的数据,现在问题就是这个时间戳怎么转换。有个问题就是像Apache的日志里面的月份是英文,英文和数字是没办法比对的,所以就要把英文转成数字。如果说现在时间里面相对位置也是英文,那就可以比较了
1:怎么得到现在的时间和以前的时间做比对
2:怎么样把月份的英文转换成数字
grep/sed/awk可以用正则去筛选日志时,如果要精确到小时、分钟、秒,则非常难以实现。但是awk提供了mktime()函数,它可以将时间转换成epoch时间值。也就是mktime函数创建指定时间,转化为时间戳。时间戳,这个概念在许多地方有用到,简单来说就是,距离1970-01-01 00:00:00的秒数,有了这个尺度,我们就可以将时间圈定在一定范围。
写法样式
$ awk 'BEGIN{print mktime("2023 08 08 13 30 10")}'
指将,2023-08-08 13:30:10转换为时间戳
案例:
日志文件
编写a.awk文件
BEGIN{
# 要筛选什么时间的日志,将其时间构建成epoch值
which_time = mktime("2023 08 08 13 41 40")
}
{
# 取出日志中的日期时间字符串部分
match($0,"^.*\\[(.*)\\].*",arr)
# 将日期时间字符串转换为epoch值
tmp_time = strptime2(arr[1])
# 通过比较epoch值来比较时间大小
if(tmp_time > which_time){
print
}
}
# 构建的时间字符串格式为:"08/Nov/2023:03:42:40+08:00"
function strptime2(str,dt_str,arr,Y,M,D,H,m,S) {
dt_str = gensub("[/:+]"," ","g",str)
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]
}
它的主要目标是筛选出在特定时间之后产生的日志。这个特定的时间被转换为Unix时间戳(epoch值)进行比较。
这个脚本的运行过程大致如下:
- 在
BEGIN
部分,将指定的日期时间(格式为"27/Jul/2023:18:36:30+0800")转换为Unix时间戳,并将其存储在which_time
变量中。 - 在
{...}
部分,对每一行日志进行操作。 - 提取每行日志的日期时间部分(格式为"[时间 时间 时间 +0800]"),并使用
strptime2
函数将其转换为Unix时间戳。 - 比较这个时间戳和
which_time
,如果大于which_time
,则打印这一行日志。
在strptime2
函数中,先将日期时间字符串中的时间部分进行格式化,然后用空格分隔开,分别提取年、月、日、时、分、秒,最后返回对应的Unix时间戳。
在mon_map
函数中,定义了一个月份到数字的映射,用于将月份的英文缩写转换为对应的两位数字。
总的来说,这个脚本的功能就是筛选出在指定时间之后产生的日志。
awk -f 脚本文件 需要读取的文件