【发布时间】:2016-12-11 06:31:50
【问题描述】:
我有一个跨越 1.5 年的访客日志文件。每行代表一个页面加载。每一行的结构如下:
2016-08-05 00:48:10 +0200 -> 170.67.51.153 -> Beijing - Beijing Shi: China -> http://example.com/?ref=1676 -> Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html) -> AS55966 Beijing Baidu Netcom Science and Technology Co., Ltd. -> Beijing Baidu Netcom Science and Technology Co. -> 0.9301
我使用“->”来分隔字段。
我的日志文件大小约为 50MB,解析整个文件以获取今天或昨天的访问者数量需要很长时间,因为这些实际行当然位于文件末尾。
我想使用 bash 命令“tac”,它是一个反向“cat”或类似的技术,以使行以相反的顺序排列。我的第一次尝试是(获取例如 2016-08-04 的每日访问者):
tac visitor_log.txt|grep 2016-08-04|cut -d " " -f 5|sort|uniq|wc -l
它当然会输出访问者计数,但不幸的是,它在读取整个文件时也很耗时,因为如果前一行匹配而实际行不匹配,则无法告诉“grep”停止匹配行'不匹配。
也许我应该在 Ruby 中模拟“tac”来有效地获取每日访问者数量?或者我应该使用“sed”中可能提供的一些触发器技术?不幸的是,我根本不知道“sed”。
【问题讨论】:
-
50MB 是一个很小的文件,处理它需要几分之一秒。你是说50GB吗? Perl 最适合处理文本文件。
-
你说“我用“->”来分隔字段”,但真正的分隔符是什么?发布问题时更改实时数据绝不是一个好主意。
cut -d " " -f 5应该生产什么?从您的数据来看,这将是第二个->,但我想您的意思是第一个Beijing? -
不知道为什么,但我想问。你为什么不为此使用服务? Google Analytics 非常容易实现,并且有一个 ruby 应用程序客户端。它比解析文本文件要快得多,而且信息量更大。否则将其加载到数据库中,因为它再次执行比文本解析好得多。
-
是的,我用“->”分隔字段,但是“cut”命令只能剪切输入一个字符,所以我用“”空格分割行,第5次分割正好IP 地址。
-
文件现在只有 50 MB,但随着流量的增加和时间的推移,它会变得巨大。
标签: ruby bash perl logging sed