grep记录格式错误的日志的最后10分钟

时间:2018-10-10 08:47:59

标签: bash

我的日志在每一行的开头都具有以下日期格式:

2018 Sep 21 17:16:27:796

我需要grep此日志的最后10分钟...有帮助吗?

我目前的实验:

tenminutesago=$(date --date='10 minutes ago' +"%Y %b %e %H:%M:%S"):999 

我的想法是将日志格式转换为渐进数字,然后检查所有大于该数字的内容。

我看到命令date +"%Y %b %e %H:%M:%S"给出了与日志格式相同的日期。命令:date +"%Y%m%e%H%M%S"以递增数字(201810041204019)

给出日期

3 个答案:

答案 0 :(得分:1)

假设您的日志行看起来像

YYYY Bbb dd HH:MM:SS:sss Some random log message is here

您可以执行以下操作:

awk -v d=$(date -d "10 minutes ago" "+%Y %m %d %T") '
     { mm = sprintf("%0.2d",(index("JanFebMarAprMayJunJulAugSepOctNovDec",$2)+2)/3) 
       s = $1 " " mm " " $3 " "$4 }
     (s >= d){print}' logfile

这个想法是将日期格式转换为可排序格式(请注意,“ Jan” <“ Mar”,但“ Feb” <“ Jan”)。这是通过将您的月份转换为两位数的数字,然后将其与正确的日期进行字符串比较来完成的。

答案 1 :(得分:0)

你可以做

for i in {10..0}; do
    d=$(date -d "$i minutes ago" +'%Y %b %e %H:%M')
    grep "$d" logfile
done

这只是将问题划分为11个连续的子任务,即从10分钟前获取所有行,从9分钟前获取所有行,依此类推,直到当前分钟。

编辑:

这是另一种解决方案,它打印从找到最后10分钟的日期戳的第一行起的所有行,不仅打印带有日期戳的行,而且还避免从头开始多次读取文件:

# build a regex pattern that matches any date in the given format from the last 10 minutes
pattern=$(date +'%Y %b %e %H:%M')
for i in {10..1}; do
    pattern+=\|$(date -d "$i minutes ago" +'%Y %b %e %H:%M')
done

# print all lines starting from the first one that matches one of the dates in the pattern
awk "/$pattern/,0" logfile

答案 2 :(得分:0)

尝试使用当前的方法,而不用秒和毫秒。

tenminutesago=$(date --date='10 minutes ago' +"%Y %b %e %H:%M")

不是十分钟到第二级,但这对于大多数情况来说已经足够了。这将为您提供时间窗口内日志的第一行。现在,您可以获取总行数并减去上一个grep的行号,然后拖尾文件。脚本可能是这样的:

LOGFILE="filename.log"
tenminutesago=$(date --date='9000 minutes ago' +"%Y %b %e %H:%M") # matching pattern
tlines=$(cat $LOGFILE | wc -l) # Total lines in file
let lines=$tlines-$(grep -n "$tenminutesago" $LOGFILE | grep -m 1 -oP "^[0-9]*" || echo $tlines) # lines after matching occurence
echo "$lines lines FOUND from the last X minutes"
tail -n $lines $LOGFILE # last lines in file

根据@Gem Taylor的建议,可以使用尾部的+ N选项来减少这一点。

LOGFILE="filename.log"
tenminutesago=$(date --date='9000 minutes ago' +"%Y %b %e %H:%M") # matching pattern
lines=$(grep -n "$tenminutesago" $LOGFILE | grep -m 1 -oP "^[0-9]*" || echo "0") # lines after matching occurence
echo "$lines lines FOUND from the last X minutes"
let lines -eq 0 && tail -n +$lines $LOGFILE # last lines in file if lines is not 0