答案 0 :(得分:2)
问题在于您比较字符串的方式过于文字化。日期按数据排序,但是awk
按字典顺序进行比较(按日期顺序“ Jan” <“ Feb”,按字符串顺序则不是)。这里可以采用多种方法,但是我建议在UNIX时代进行比较。
$ tend=$(date "+%s")
$ tstart=$(date --date="5 minutes ago" "+%s")
$ awk -F '[][]' '!/PHP Warning/{next}
{ cmd="date --date=\""$2"\" \"+%s\""
time=((cmd | getline line) > 0 ? line : -1)
close(cmd) }
(time == -1) { exit 1 }
(tend <= time && time <= tstart)
' tstart=$tstart tend=$tend <logfile>
注意::如果文件很大,这将对date
执行大量调用。
另一种方法可能是从GNU awk调用mktime
或将时间字符串重新格式化为 yyyymmddHHMMSS 。这使您可以对字符串使用字典顺序:
$ tstart=$(date -d="5 minutes ago" "+%Y%m%d%H%M%S"")
$ tend=$(date "+%Y%m%d%H%M%S"")
$ awk 'BEGIN{ month["Jan"]="01"; month["Feb"]="02"; month["Mar"]="03"
month["Arp"]="04"; month["May"]="05"; month["Jun"]="06"
month["Jul"]="07"; month["Aug"]="08"; month["Sep"]="09"
month["Oct"]="10"; month["Nov"]="11"; month["Dec"]="12" }
!/PHP Warning/{next}
{ time=$4; gsub(/:/,"",time); year=substr($5,1,4);
date=sprintf(%4s%2s%0.2d%6s,year,month[$2],$3,time) }
}
(tstart <= date && tend <= date)
' tend=$tend tstart=$tstart <logfile>
或根据Ed Morton的建议:
$ awk '!/PHP Warning/{next}
{ year=substr($5,1,4)
month=(index("JanFebMarAprMayJunJulAugSepOctNovDec",$2)+2)/3
time=$4; gsub(/:/,"",time);
date=sprintf(%4s%0.2d%0.2d%6s,year,month,$3,time)
}
(tstart <= date && tend <= date)
' tend=$end tstart=$tstart <logfile>
相关文章可以在这里找到:Regex to match logfile custom date formats
答案 1 :(得分:1)
这对我来说是bash + gawk的工作:
#!/bin/bash
LC_ALL=C gawk -v limit=$(date --date="5 minutes ago" "+%s") '
function epoch(month, day, hhmmss, year) {
gsub(/:/, " ", hhmmss)
sub(/\]/, "", year)
month = (index("JanFebMarAprMayJunJulAugSepOctNovDec", month) + 2) / 3
return mktime(year" "month" "day" "hhmmss)
}
/PHP Warning/ && epoch($2, $3, $4, $5) > limit
' "test.log"
如果您还想包含致命错误,只需删除/PHP Warning/ &&
或根据需要调整正则表达式即可(例如/Warning|error/
或类似的东西)。