我正在尝试在日志文件中查找最近5分钟的模式“ INFO:服务器启动”。
这是我要从中查找模式的行:“ INFO | jvm 1 | main | 2018/07/09 00:11:29.077 | INFO:服务器启动时间为221008 ms”
模式即将来临,但是我需要缩短代码或为其创建循环。
我试图创建一个循环,但无法正常工作。这是我的没有循环的代码,可以正常工作:
#!/bin/bash
#Written by Ashutosh
#We will declare variables with date and time of last 5 mins.
touch /tmp/a.txt;
ldt=$(date +"%Y%m%d");
cdt=$(date +"%Y/%m/%d %H:%M");
odtm5=$(date +"%Y/%m/%d %H:%M" --date "-5 min");
odtm4=$(date +"%Y/%m/%d %H:%M" --date "-4 min");
odtm3=$(date +"%Y/%m/%d %H:%M" --date "-3 min");
odtm2=$(date +"%Y/%m/%d %H:%M" --date "-2 min");
odtm1=$(date +"%Y/%m/%d %H:%M" --date "-1 min");
## Finding the pattern and storing it in a file
grep -e "$odtm1" -e "$cdt" -e "$odtm2" -e "$odtm3" -e "$odtm4" -e
"$odtm5" /some/log/path/console-$ldt.log
> /tmp/a.txt;
out=$(grep 'INFO: Server startup in' /tmp/a.txt);
echo "$out"
## remove the file that contains the pattern
rm /tmp/a.txt;
我也尝试使用sed,但是date函数无法使用它。 有人可以给我新的带循环的更改脚本吗?
答案 0 :(得分:4)
采用原始逻辑:
time_re='('
for ((count=5; count>0; count--)); do
time_re+="$(date +'%Y/%m/%d %H:%M' --date "-$count min")|"
done
time_re+="$(date +'%Y/%m/%d %H:%M'))"
ldt=$(date +'%Y%m%d')
awk -v time_re="$time_re" '
$0 ~ time_re && /INFO: Server startup in/ { print $0 }
' "/some/log/path/console-$ldt.log"
性能增强当然是可能的-通过将日志分为开始时间可以使速度更快-但上面的内容解决了明确的问题(关于使用循环生成时间窗口的问题)。请注意,它将变得笨拙-例如,您不希望使用它来搜索最后一天,因为正则表达式将变得完全不合理。
答案 1 :(得分:1)
您需要的声音是:
nil
不需要显式循环或多次调用NoMethod Error for nil class
。
答案 2 :(得分:1)
这里有一个bash
脚本可以完成任务(感谢Charles的改进):
#!/bin/bash
limit=$(date -d '5 minutes ago' +%s)
today_logs="/some/log/path/console-$(date +'%Y%m%d').log"
yesterday_logs="/some/log/path/console-$(date +'%Y%m%d' -d yesterday).log"
tac "$today_logs" "$yesterday_logs" \
| while IFS='|' read -r prio jvm app date log; do
[ $(date -d "$date" +%s) -lt "$limit" ] && break
echo "|$jvm|$prio|$app|$date|$log"
done \
| grep -F 'INFO: Server startup in' \
| tac
与原始脚本相比,它具有以下优点:
将上面的代码与Ed Morton's answer混合,您将得到:
#!/bin/bash
limit=$(date -d '5 minutes ago' +'%Y/%m/%d %H:%M')
today_logs="/some/log/path/console-$(date +'%Y%m%d').log"
yesterday_logs="/some/log/path/console-$(date +'%Y%m%d' -d yesterday).log"
tac "$today_logs" "$yesterday_logs" \
| awk -v stop="$limit" -F'[[:space:]]*[|][[:space:]]*' '
($4 < stop) { exit }
/INFO: Server startup in/
' \
| tac