查看当前的时间戳
date +%s
[root@yangxingquan httpd]# date +%s
1691465408
一般说来就是我们执行 date命令看到的时间,linux系统下所有的时间调用都是使用的这个
时间。
组成部分:主要由年月日时分秒,以及时区组成
查看当前时间
[root@yangxingquan httpd]# date
2023年 08月 08日 星期二 11:28:57 CST
grep/sed/awk用正则去筛选日志时,如果要精确到小时、分钟、秒,则非常难以实现。
但是awk提供了mktime()函数,它可以将时间转换成epoch时间值。
# 2019-11-10 03:42:40转换成epoch为1970-01-01 00:00:00
$ awk 'BEGIN{print mktime("2019 11 10 03 42 40")}'
借此,可以取得日志中的时间字符串部分,再将它们的年、月、日、时、分、秒都取出来,然后放入mktime()构建成对应的epoch值。因为epoch值是数值,所以可
以比较大小,从而决定时间的大小。
下面strptime1()实现的是将2019-11-10T03:42:40+08:00格式的字符串转换成epoch值,
然后和which_time比较大小即可筛选出精确到秒的日志。
测试:
[root@yangxingquan httpd]# awk 'BEGIN{print mktime("2019 11 10 03 42 40")}'
1573328560
可以利用patsplit来取时间中的数字
BEGIN{
#要筛选什么时间的日志,将其时间构建成epoch值
which_time = mktime("2023 8 7 11 05 54")
}
{
#取出日志中的日期时间字符串部分
match ($0, "^.*\\[(.*)\\].*" , arr)
#将日期时间字符串转换为epoch值
tmp_time = strptime1(arr[1])
#通过比较epoch值来比较时间大小
if(tmp_time > which_time){print}}
#构建的时间字符串格式为:"2023-8-7T11:05:54+08:80"
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=arr[6]
#通过mktime构建字符串
return mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))
}
程序运行逻辑先定义一个筛选时间将其转化成epoch值,然后利用正则表达式取出日志中的时间字符串将其放入arr[]数组中,循环调用strptime1()函数循环判断
#patsplit:使用正则表达式来匹配字符串,将匹配成功的部分赋给对于变量,最后显示出来。
BEGIN{
# 要筛选什么时间的日志,将其时间构建成epoch值
which_time = mktime("2023 8 7 11 05 54")
}
{
# 取出日志中的日期时间字符串部分
match($0,"^.*\\[(.*)\\].*",arr)
# 将日期时间字符串转换为epoch值
tmp_time = strptime2(arr[1])
# 通过比较epoch值来比较时间大小
if(tmp_time > which_time){
}
}
# 构建的时间字符串格式为:"10/Nov/2019:23:53:44+08:00"
function strptime2(str ,dt_str,arr,Y,M,D,H,m,S) {
dt_str = gensub("[/:+]"," ","g",str)
# dt_sr = "7 Aug 2023 11 05 54 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]
}
程序运行逻辑与例1一样,只不过不同时间格式不一样需要利用gensub()函数将/:替换成空格,再用split()将函数利用空格分隔,将英文月份转换成数字即可。
使用 awk 命令 -f 选项 从脚本文件中读取 access.log日志文件,从而进行筛选;