访问日志或多或少是按时间排序的,但是要按时间(uniq -c
)聚合连接,您需要对它们进行更多排序。对于巨大的访问日志,排序的效率非常低,因为它在打印任何内容之前对整个文件进行缓冲和排序。
您是否知道排序或排序版本的任何选项,可以一次仅对给定数量的行进行排序,打印该块?
我搜索了以下关键字:“流排序”、“块排序”、“近似排序”。整个说明书我都看完了,没用。设置缓冲区大小 (-S) 对此没有影响。
答案1
tail -f access_log | awk -v 'cmd=sort --OPTION-IN-QUESTION | uniq -c' '
{print $4, $1 | cmd}
NR % 1000 == 0 {close(cmd)}'
答案2
尝试split --filter
:
split --lines 1000 --filter 'sort ... | sed ... | uniq -c' access.log
这将分成access.log
1000 行的块,并通过给定的过滤器对每个块进行管道传输。
如果要单独保存每个块的结果,可以$FILE
在过滤器命令中使用并可能指定前缀(默认为x
):
split --lines 1000 --filter '... | uniq -c >$FILE' access.log myanalysis-
这将生成一个文件,其中包含处理第一个块、第二个块等myanalysis-aa
的结果。myanalysis-ab
该--filter
选项split
是在 GNU coreutils 8.13(2011 年 9 月发布)中引入的。
答案3
sort
它不是万能的灵丹妙药,您应该使用其他适当的工具在数据到达之前对其进行过滤sort
。tail
应该可以完成这项工作。例如,要对最后 100 行进行排序,您可以这样做:
tail -100 /var/log/foo.log | sort
答案4
如果您只想对文件的一部分进行排序,您可以使用例如sed
.
对第 15000 至 25000 行进行排序:
sed -n '15000,25000p' | sort
如果您要保留排序的文件,您也可以考虑split
。
见人split
。