Назад | Перейти на главную страницу

как сгруппировать возвращаемую строку по метке времени и показать, сколько хитов в группе

Я анализирую журналы доступа httpd, чтобы выяснить, какие из сканеров нашего устройства Google бомбардируют мои веб-серверы и когда. Если я наберу команду:

grep google /path/to/access_log | awk '{print $4, $14}'

Я могу получить очень большой (как я уже сказал, меня бомбардируют) возвратный набор, по крайней мере, 4 в секунду. Я хочу иметь возможность сгруппировать указанный выше результат, установленный по метке времени, и вернуть строку, содержащую количество совпадений в секунду. В идеале я бы хотел иметь что-то похожее на

04/Aug/2011:15:56:16 Crawler1 6
04/Aug/2011:15:56:16 Crawler2 10
04/Aug/2011:15:56:17 Crawler1 8
04/Aug/2011:15:56:18 Crawler1 12

Где первое - это временная метка, второе - это 14-е поле, идентификатор Google Crawler, а третье - счетчик. Порядок столбцов не имеет значения.

awk '/google/ { print substr($4, 2, length($4)-1), $14 }' access_log | sort -rn | uniq -c | awk '{ print $2"\t"$3"\t"$1 }'

Это можно сделать в одной awk, подсчитывая попадания за одну секунду с использованием массивов, но это сложно проверить без ввода образца. Угадаем:

awk '/google/ {
  ts=$4
  crawler=$14

  if (ts != lts) {
    for(c in count) {
      print lts " " c " " count[c]
      delete count[c]
    }

    lts=ts
  }

  count[crawler]++
}END{
  for(c in count) {
    print lts " " c " " count[c]
  }
}' access_log