Проблема в том, что вы сравниваете свои строки слишком буквально. Даты упорядочены по данным, но awk
сравнивает лексикографическое («январь» <«февраль» для даты, но для строки это не так). Здесь можно использовать различные подходы, но я предлагаю сделать сравнение в эпоху UNIX. </p>
$ 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
, если ваш файл большой.
Другим подходом может быть вызов mktime
из GNU awk или переформатирование вашей временной строки в ггггммдд ЧЧММСС . Это позволяет использовать лексикографический порядок для строк:
$ 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>
Или по предложению Эд Мортон :
$ 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 для соответствия форматам даты в лог-файле