Как разделить существующий лог-файл apache по месяцам?
Как можно разделить существующие лог-файлы 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)"
Вот мое решение, вдохновленное ответом Стива ниже:
Один из способов использования 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
Для файла журнала размером 150 МБ программа "Принятый ответ" от chepner заняла 70 секунд на 8-ядерном Xeon E31270 с частотой 3,4 ГГц, а этот метод занял 5 секунд.
Оригинальное вдохновение: /questions/12044034/kak-razdelit-suschestvuyuschij-log-fajl-apache-po-mesyatsam/12044043#12044043
2 ответа
Один из способов использования 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
Отличный ответ @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» может принять вызов и сделать это за нас, обработав полученные имена файлов вторым скриптом?