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.
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.
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.