在两个时间戳之间提取日志的最有效方法是什么?

时间:2017-03-19 18:17:13

标签: awk grep text-processing

我有一个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这样的不同语言的东西会更好? 感谢

4 个答案:

答案 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将起作用。

否则,虽然有点笨重,但您可以使用this查找感兴趣日期的第一个和最后一个匹配项,然后使用sed选择该范围。

答案 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。