fgrep '2064351200' example.log | fgrep 'action: example'
这可以很好地处理较小的文件,但是使用5gb的日志文件,它的速度无法忍受.我在网上看到使用sed或awk来提高性能(或者甚至可能是两者的组合)都很棒,但我不确定这是如何实现的.例如,使用awk,我有一个典型的命令:
awk '/2064351200/ {print}' example.log
基本上我的最终目标是能够打印/返回包含字符串的记录(或行号)(可能高达4-5,并且我读过管道很糟糕)以便在日志文件中有效匹配.
在旁注中,在bash shell中,如果我想使用awk并进行一些处理,那是如何实现的呢?例如:
BEGIN { print "File\tOwner" } { print $8,"\t",\ $3} END { print " - DONE -" }
这是一个非常简单的awk脚本,我认为有一种方法可以将它放入一个单行bash命令中?但我不确定结构是怎样的.
在此先感谢您的帮助.干杯.
time fgrep '2064351200' example.log >/dev/null time egrep '2064351200' example.log >/dev/null time sed -e '/2064351200/!d' example.log >/dev/null time awk '/2064351200/ {print}' example.log >/dev/null
传统上,egrep应该是最快的(是的,比fgrep更快),但是一些现代实现是自适应的并且自动切换到最合适的搜索算法.如果您有bmgrep(使用Boyer-Moore搜索算法),请尝试使用.通常,sed和awk会更慢,因为它们被设计为更通用的文本操作工具,而不是针对特定的搜索工作进行调整.但它确实取决于实现,找到的正确方法是运行测试.每次运行它们几次,这样你就不会被缓存和竞争过程搞砸了.
正如@Ron指出的那样,您的搜索过程可能是磁盘I / O绑定.如果您将多次搜索同一个日志文件,则首先压缩日志文件可能会更快;这样可以更快地读取磁盘,但需要更多的cpu时间来处理,因为它必须首先解压缩.尝试这样的事情:
compress -c example2.log >example2.log.Z time zgrep '2064351200' example2.log.Z >/dev/null gzip -c example2.log >example2.log.gz time zgrep '2064351200' example2.log.gz >/dev/null bzip2 -k example.log time bzgrep '2064351200' example.log.bz2 >/dev/null
我只是用一个相当可压缩的文本文件运行了一个快速测试,发现bzip2压缩得最好,但后来耗费了更多的cpu时间进行解压缩,所以zgip选项总体来说最快.您的计算机将具有与我的不同的磁盘和cpu性能,因此您的结果可能会有所不同.如果您有任何其他压缩机,也可以尝试它们,和/或尝试不同级别的gzip压缩等.
说到预处理:如果你一遍又一遍地搜索同一个日志,有没有办法预先选择你可能感兴趣的日志行?如果是这样,将它们变成一个较小的(可能是压缩的)文件,然后搜索它而不是整个文件.与压缩一样,您可以预先花费一些额外的时间,但每次单独搜索都会更快.
关于管道的注意事项:其他条件相同,通过多个命令管理一个巨大的文件将比单个命令完成所有工作要慢.但是这里的所有事情都不相同,如果在管道中使用多个命令(这是zgrep和bzgrep所做的)会为你带来更好的整体性能,那就去吧.另外,请考虑您是否实际将所有数据传递到整个管道.在你给出的例子中,fgrep’2064351200’example.log | fgrep’action:example’,第一个fgrep将丢弃大部分文件;管道和第二个命令只需处理包含’2064351200’的小部分日志,因此减速可能可以忽略不计.
tl;博士测试所有的事情!
编辑:如果日志文件是“实时”(即添加新条目),但它的大部分是静态的,您可能可以使用部分预处理方法:压缩(&可能预扫描)日志,然后当扫描使用压缩(& /预扫描)版本加上自执行预扫描后添加的日志部分的尾部.像这样的东西:
# Precompress: gzip -v -c example.log >example.log.gz compressedsize=$(gzip -l example.log.gz | awk '{if(NR==2) print $2}') # Search the compressed file + recent additions: { gzip -cdfq example.log.gz; tail -c +$compressedsize example.log; } | egrep '2064351200'
如果您要进行多个相关搜索(例如特定请求,然后是该请求的特定操作),您可以保存预扫描版本:
# Prescan for a particular request (repeat for each request you'll be working with): gzip -cdfq example.log.gz | egrep '2064351200' > prescan-2064351200.log # Search the prescanned file + recent additions: { cat prescan-2064351200.log; tail -c +$compressedsize example.log | egrep '2064351200'; } | egrep 'action: example'