如何按月份拆分现有的Apache日志文件?

10

如何将现有的 Apache 日志文件按月份分割成单独的文件?

我已经搜遍了网络,但是找不到任何帮助我分割现有文件的方法。是的,我知道 logrotate 和 cronolog 等工具。但是我没能找到任何可以帮助我分割现有文件的工具。

是否有 awk 脚本或其他工具可以做到这一点?

以下是数据片段:

124.115.5.11 - - [30/May/2011:23:21:37 -0500] "GET / HTTP/1.0" 200 206492 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322;TencentTraveler)"
58.61.164.39 - - [31/May/2011:00:36:35 -0500] "GET / HTTP/1.0" 200 206492 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322;TencentTraveler)"
114.80.93.55 - - [31/May/2011:01:42:17 -0500] "GET / HTTP/1.0" 200 206492 "-" "Sosospider+(+http://help.soso.com/webspider.htm)"
114.80.93.73 - - [31/May/2011:02:03:44 -0500] "GET / HTTP/1.0" 200 206492 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322;TencentTraveler)"
123.125.71.98 - - [31/May/2011:12:33:30 -0500] "GET / HTTP/1.1" 103 24576 "-" "Baiduspider+(+http://www.baidu.com/search/spider.htm)"
220.181.108.187 - - [31/May/2011:12:33:55 -0500] "GET / HTTP/1.1" 103 24576 "-" "Baiduspider+(+http://www.baidu.com/search/spider.htm)"
123.125.71.117 - - [31/May/2011:13:27:56 -0500] "GET / HTTP/1.1" 103 24576 "-" "Baiduspider+(+http://www.baidu.com/search/spider.htm)"
123.125.71.78 - - [31/May/2011:16:45:48 -0500] "GET /node/54 HTTP/1.1" 200 3219 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
124.115.1.8 - - [31/May/2011:19:59:58 -0500] "GET / HTTP/1.1" 200 206492 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
123.125.71.69 - - [31/May/2011:22:05:46 -0500] "GET / HTTP/1.1" 200 206492 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"

以下是我受到Steve下面回答启发后的方案:

使用 awk 的一种方法:

awk 'BEGIN {
    split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ", months, " ")
    for (a = 1; a <= 12; a++)
        m[months[a]] = a
}
{
    split($4,array,"[:/]");
    year = array[3]
    month = sprintf("%02d", m[array[2]])

    print > FILENAME"-"year"_"month".txt"
}' incendiary.ws-2009
这将输出类似以下的文件:
incendiary.ws-2010-2010_04.txt
incendiary.ws-2010-2010_05.txt
incendiary.ws-2010-2010_06.txt
incendiary.ws-2010-2010_07.txt

在一个150MB的日志文件上,chepner所提供的被接受的答案在3.4 GHz 8 Core Xeon E31270处理器上花费了70秒,而这种方法只需要5秒

原始灵感来源:https://dev59.com/AGgt5IYBdhLWcg3w7BuL#11714105


1
知道awk(或其他类似工具)的人不一定了解或能够访问您要处理的数据文件,如果可能的话,提供一些输入/输出示例以展示你正在处理的数据及想要得到的结果会更好。 - Levon
我已经实现了你的优秀建议。 - Theodore R. Smith
2个回答

12

使用 awk 的一种方法:

awk '{ split($4,array,"/"); print > array[2] ".txt" }' file.txt

这将输出如下文件:

May.txt
June.txt
July.txt
etc

编辑:

也许你想要把年份分开:

awk '{ split($4,array,"[:/]"); print > array[2] array[3] ".txt" }' file.txt

这将输出类似以下的文件:

May2011.txt
May2012.txt
July2011.txt
etc

1
我已经修改了你的算法,使其格式为FILENAME-YYYY_MM。我将它放在了我的问题中。 - Theodore R. Smith

1
很棒的回答@steve,我只是将你的例子中的术语反转,以便年份成为生成文件名的第一部分,这样文件排序至少还算半正常。
awk '{ split($4,array,"[:/]"); print > array[3] "-" array[2] ".log" }' file.txt

这就是你得到的(不理想)
2021-Apr.log
2021-Aug.log
2021-Dec.log
2021-Feb.log
2021-Jan.log
2021-Jul.log
2021-Jun.log
2021-Mar.log
2021-May.log
2021-Nov.log
2021-Oct.log
2021-Sep.log

理想情况下,我会按%Y-%m而不是%Y-%b排序。也许一个“awk巫师”可以接受这个挑战,并通过处理结果文件名来使用第二个脚本完成它?提示:Unix将月份名称转换为数字

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接