Extract data from log [duplicate]

2019-09-19 19:38发布

问题:

This question already has an answer here:

  • bash only email if occurrence since last alert 1 answer

I have logs in format

##<01-Mar-2015 03:48:18 o'clock GMT> <info> 
##<01-Mar-2015 03:48:20 o'clock GMT> <info>
##<01-Mar-2015 03:48:30 o'clock GMT> <info>
##<01-Mar-2015 03:48:39 o'clock GMT> <info>

I got to write shell script to extract data of last 5 minutes from the last recorded data in the log file and then search a string in it.I am new to shell script , I used grep command but its of no use.Can anyone help me here. I tried the below script

#!/bin/bash

H=1  ## Hours
LOGFILE=/path/to/logfile.txt

X=$(( H * 60 * 60 )) ## Hours converted to seconds

function get_ts {
DATE="${1%%\]*}"; DATE="${DATE##*\[}"; DATE=${DATE/:/ };                 DATE=${DATE//\// }
TS=$(date -d "$DATE" '+%s')
}

get_ts "$(tail -n 1 "$LOGFILE")"
LAST=$TS

while read -r LINE; do
get_ts "$LINE"
(( (LAST - TS) <= X )) && echo "$LINE"
done < "$LOGFILE"

and on running it get the below error get_ts: DATE=${DATE/:/ }: 0403-011 The specified substitution is not valid for this command.

回答1:

IF you use awk, you can use date to get data for example last 5 minutes like this:

awk '$0>=from' from="$(date +"##<%d-%b-%Y %H:%M:%S" -d -5min)" logile

PS, you need the date command to match your format.



回答2:

I'd parse the date into seconds since epoch and compare that with the system time:

TZ=GMT awk -F '[#<> :-]+' 'BEGIN { split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec", mnames, ","); for(i = 1; i <= 12; ++i) m[mnames[i]] = i } mktime($4 " " m[$3] " " $2 " " $5 " " $6 " " $7) + 300 >= systime()' filename

The -F '[#<> :-]+' is to split the date into individual parts, so that $2 is the day, $3 the month, $4 the year, and so forth. Then the code works as follows:

BEGIN {
  # build a mapping from month name to number (to use in mktime)
  split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec", mnames, ",")
  for(i = 1; i <= 12; ++i) m[mnames[i]] = i
}

# build a numerically comparable timestamp from the split date, and
# select all lines whose timestamp is not more than 300 seconds behind
# the system time.
mktime($4 " " m[$3] " " $2 " " $5 " " $6 " " $7) + 300 >= systime()

Setting the TZ environment variable to GMT (with TZ=GMT before the awk call) will make mktime interpret the time stamps as GMT.