首页 > 解决方案 > 如何从文件中生成多个计数而无需多次重新读取?

问题描述

我有大量的 HTTP 访问日志文件,我正在尝试为特定查询字符串生成每小时计数。显然,正确的解决方案是将所有内容转储到 splunk 或 graylog 或其他内容中,但我目前无法为这一一次性交易设置所有这些。

快速而肮脏的是:

for hour in 0{0..9} {10..23}
do
  grep $QUERY $FILE | egrep -c "^\S* $hour:"
  # or, alternately
  # egrep -c "^\S* $hour:.*$QUERY" $FILE
  # not sure which one's better
done

但是这些文件平均有 15-20M 行,我真的不想解析每个文件 24 次。解析文件并一次性计算每个实例的效率要高得多$hour。有没有办法做到这一点?

标签: bashgrep

解决方案


您可以要求 grep 输出每行的匹配部分,-o然后用于uniq -c计算结果:

grep "$QUERY" "$FILE" | grep -o "^\S* [0-2][0-9]:" | sed 's/^\S* //' | uniq -c

sed命令仅保留两位数小时和冒号,如果需要,您也可以使用另一个 sed 表达式将其删除。

注意事项:此解决方案适用于 GNU grep 和 GNU sed,并且在没有日志条目的几个小时内不会产生输出,而不是“0”。感谢@EdMorton 在评论中指出这些问题,以及在上述答案中修复的其他问题。


推荐阅读