我有一个bash脚本,可以从两个时间戳之间的文件中提取日志。但是,随着文件变大(超过2 GB,高达10GB),完成时间(超过20分钟)需要相当长的时间
我的日志结构如下所示:
087B0037 08AD0056 03/09 02:40:40 [MMS:Main,INF] MMS state changed
087B0037 096100BE 03/09 02:40:41 [Navigation,INF] CDDClient Initialize...
EndeavourDriver: 03/09/2017 02:40:42 :
00400004 047B0012 EndeavourDriver: 71 [SDIO87871]:
087B0037 0BE10002 03/10 06:40:40 [NNS:NNS,INF] Initializing NNS thread id 0x0BE10002...
087B0037 08AD0056 03/10 06:40:40 Initialized state: BITServer
我的脚本使用以下命令:
grep -a -A 1000000 "03/09" fileName.txt | grep -a -B 1000000 "03/10"
但这需要太长时间。如果我添加时间(例如" 03/09 02:")速度更快但日志并不总是在运行,那么某些时间值可能会丢失。 日期值总是在第3列,所以我尝试使用awk:
awk '$3 >= "03/09" && $3 <= "03/10"' fileName.txt
但这不会收集以下内容:
EndeavourDriver: 03/09/2017 02:40:42 :
00400004 047B0012 EndeavourDriver: 71 [SDIO87871]:
我对awk,sed和grep不太熟悉所以任何建议都会受到赞赏。也许像python这样的不同语言的东西会更好? 感谢
答案 0 :(得分:1)
如果您的日志文件是按时间顺序排列的,并且您只想提取一两天,这可能对您有用
awk '$3=="03/09"{s=1} s; $3=="03/11"{exit}' log_file
将从03/09的第一个实例开始,并以03/11的第一个实例退出。如果文件中的第二天可能不存在,您可以将其更改为$3>"03/10"
,以使其在错过的日期更加健壮。
提前退出可能会加速在文件开头的日期工作,但不会在以后的几天内工作,因为它仍然需要扫描文件。
此外,您的多行记录可能会出现意外匹配,因为您需要定义更好的记录结构或回退到昂贵的正则表达式匹配。
请注意,提取的最后一行会有意地具有退出值,以便您可以检查误报匹配。
答案 1 :(得分:0)
IMO我认为您应该重新格式化日志输出的方式,以便它们采用一致的格式(即时间戳始终位于第一列),然后您的awk将起作用。
答案 2 :(得分:0)
试试这个awk解决方案 -
cat time.awk
{
if($4 ~ /^[0-9][0-9]:[0-9][0-9]:[0-9][0-9]$/ && $3 >= "03/09" && $3 <= "03/10")
print $0
else if($3 ~ /^[0-9][0-9]:[0-9][0-9]:[0-9][0-9]$/ && $2 >= "03/09/2017" && $2 <= "03/10/2017")
{
x=$0
print x;
getline n
print n
}
else
print ""
}
输入文件:
cat f
087B0037 08AD0056 03/09 02:40:40 [MMS:Main,INF] MMS state changed
087B0037 096100BE 03/09 02:40:41 [Navigation,INF] CDDClient Initialize...
EndeavourDriver: 03/09/2017 02:40:42 :
00400004 047B0012 EndeavourDriver: 71 [SDIO87871]:
087B0037 0BE10002 03/10 06:40:40 [NNS:NNS,INF] Initializing NNS thread id 0x0BE10002...
087B0037 08AD0056 03/10 06:40:40 Initialized state: BITServer
087B0037 08AD0056 04/10 06:40:40 Initialized state: BITServer
处理:
awk -f time.awk f
087B0037 08AD0056 03/09 02:40:40 [MMS:Main,INF] MMS state changed
087B0037 096100BE 03/09 02:40:41 [Navigation,INF] CDDClient Initialize...
EndeavourDriver: 03/09/2017 02:40:42 :
00400004 047B0012 EndeavourDriver: 71 [SDIO87871]:
087B0037 0BE10002 03/10 06:40:40 [NNS:NNS,INF] Initializing NNS thread id 0x0BE10002...
087B0037 08AD0056 03/10 06:40:40 Initialized state: BITServer
答案 3 :(得分:0)
您是否尝试过限制比赛次数?并使用fgrep?这可能会显着缩短处理时间:
fgrep -a -A -m 1 1000000 "03/09" fileName.txt | fgrep -a -B 1000000 "03/10"
Here也是加快速度的其他一些想法。特别是使用fgrep而不是grep。