awk的经典实战案例——筛选给定时间范围内的日志

目录

一、时间戳及当地时间的转换:

1、概念

2、时间的两种表示方式:

二、时间类内置函数

mktime

示例:2019-11-10 03:42:40转换成epoch为1970-01-01 00:00:00

三、筛选给定时间范围内的日志实例

实例1

 实例2:精确到秒的日志1

 实例3:精确到秒的日志2


一、时间戳及当地时间的转换:

1、概念

  新纪元(epoch):时间的开始, 时间值为0。对于Unix,这个时间是1970.1.1。

  夏时制(Daylight Saving Time:DST):又称“日光节约时制”和“夏令时间”,是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时间”。一般在天亮早的夏季人为将时间提前一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。

  时区:世界按照经度被划分为24个时区。

2、时间的两种表示方式:

  时间戳:从新纪元开始到当前时间的秒数。

  当地年月日时间:组成部分为年、月、日、时、分、秒、是否是夏时制、当地时区

二、时间类内置函数


awk常用于处理日志,它支持简单的时间类操作。有下面3个内置的时间函数:

  • mktime("YYYY MM DD HH m SS [DST]")  :  构建一个时间,返回这个时间点的秒级epoch,构建失败则返-1
  • systime()  : 返回当前系统时间点,返回的是秒级epoch值
  • strftime([format [,timestamp [,utc-flag] ] J)  : 将时间按指定格式转换为字符串并返回转的结果字符串

注意:awk构建时间时都是返回秒级的epoch值,表示从 1970-1-01 00:00:00 开始到指定时间已经过的秒数。

awk 'BEGIN{print systime();print mktime( "2019 2 29 12 32 59")}
1572364974
1551414779

grep/sed/awk用正则去筛选日志时,如果要精确到小时、分钟、秒,则非常难以实现。

但是awk提供了mktime()函数,它可以将时间转换成epoch时间值。

mktime


        mktime在构建时间时,如果传递的DD给定的值超出了月份MM允许的天数,则自动延申到下个月。例如,指定”2019229 12 30 59"中2月只有28号,所以构建出来的时间是 2019-83-01 12:30:59此外,其它部分也不限定必须在范围内。例如, 2019 2 23 12 32 65 的秒超出了59,那么多出来的秒数将进位到分钟。

示例:2019-11-10 03:42:40转换成epoch为1970-01-01 00:00:00

[root@localhost ~]# awk 'BEGIN{print mktime("2019 11 10 03 42 40")}'
1573375360

        上述代码首先取得日志中的时间字符串部分,再将它们的年、月、日、时、分、秒都取出来,然后放入mktime()构建成对应的epoch值。因为epoch值是数值,所以可以比较大小,从而决定时间的大小。

三、筛选给定时间范围内的日志实例

实例1

         strptime1 () 实现的是将 2019-11-10T20:25:39+08:00 格式的字符串转换成 epoch 值,然后和 mktime构建字符串可筛选出精确到秒的日志。

# 2019-11-10T20:25:39+08:00

BEGIN{
    #时间字符串
    str="2019-11-10T20:25:39+08:00"
    # 可以使用match  gsub  gensub ,先将各个标点符号替换成空格,然后再用split进行字段划分
    #patsplit:使用正则表达式来匹配字符串,将匹配成功的部分显示出来,并保存到数组当中.需要指定:字符串,数组,正则表达式,由此已经取到了年月日时分秒
    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构建字符串
    print mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))
}

awk的经典实战案例——筛选给定时间范围内的日志_第1张图片

 实例2:精确到秒的日志1

        实例2: 实现的是将 2019-11-10T03:42:40+08:00 格式的字符串转换成 epoch 值,然后和 which_time 比较大小即可筛选出精确到秒的日志。

BEGIN{
    #要筛选什么时间的日志,将其时间构建成epoch值
    which_time = mktime("2019111083 42 40")
}


{
    #取出日志中的日期时间字符串部分
    match ($O, "^,*\l[(.*)ll].*" , arr)

    #将日期时间字符串转换为epoch值
    tmp_time = strptime1(arr[1])

    #通过比较epoch值来比较时间大小
    if(tmp_time > which_time){print}}
}

    #构建的时间字符串格式为:"2019-11-10T83:42:40+08:80"
    function strptime1 (str,arr ,Y,M,D, H, m, S) {
    dt_str = gensub( "[/:+]"," ", "g",str)
    #10 Nov 2019 23 53 4408 00
    split(dt_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))
}

 实例3:精确到秒的日志2

示例3实现的是将10/Nov/2019:23:53:44+08:00格式的字符串转换成epoch值,然后和which_time比较大小即可筛选出精确到秒的日志。

BEGIN{
  # 要筛选什么时间的日志,将其时间构建成epoch值
  which_time = mktime("2019 11 10 03 42 40")
}

{
  # 取出日志中的日期时间字符串部分
  match($0,"^.*\\[(.*)\\].*",arr)
  
  # 将日期时间字符串转换为epoch值
  tmp_time = strptime2(arr[1])
  
  # 通过比较epoch值来比较时间大小
  if(tmp_time > which_time){
    print 
  }
}

# 构建的时间字符串格式为:"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 = "10 Nov 2019 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]
}

awk的经典实战案例——筛选给定时间范围内的日志_第2张图片

你可能感兴趣的:(网络渗透防御,linux,服务器,运维,安全)