Предполагая, что все системы работают с одним и тем же дистрибутивом, сгенерируйте RPM (при условии, что это формат пакета, который использует ваш дистрибутив) и разверните его. Это имеет множество преимуществ и практически не имеет недостатков.
С помощью чего-то вроде этого вы можете выделить доступные минуты:
root@debian:# awk -F" " '{print $2" "$3}' b.txt |cut -f1-2 -d: |uniq
01/01/2010 20:56
02/01/2010 01:39
02/01/2010 01:40
02/01/2010 20:56
Затем вы можете назначить массив с этими значениями
Исправленный код:
readarray -t stamps < <(awk -F" " '{print $2" "$3}' b.txt |cut -f1-2 -d: |uniq)
for stamp in "${stamps[@]}";do
ev=$(grep "$stamp" b.txt |wc -l)
echo "In $stamp found $ev events "
#if [ "$ev" -gt 60 ]; then
# do the stuff
#fi
done
Вывод:
In 01/01/2010 20:56 found 7 events
In 02/01/2010 01:39 found 11 events
In 02/01/2010 01:40 found 4 events
In 02/01/2010 20:56 found 7 events
Это не самое эффективное решение, но вы можете сначала подсчитать количество событий для каждой минуты, а затем выполнить поиск файла для каждой из этих минут, когда счетчик> = 60.
sort -k 2,3 your_log_file \
| uniq -c -s 8 -w 16 \
| while read count _ date time _; do
[ "$count" -ge 60 ] && grep -F " $date ${time%:*}" your_log_file
done
Примечания:
Если ваш файл полон событий, велика вероятность, что вы в конечном итоге будете выполнять с ним многочисленные команды grep
. Лучшим решением будет последовательное чтение файла журнала и запоминание строк за последнюю минуту. Когда вы дойдете до следующей минуты, распечатайте эти строки, если их количество больше 60. См. Ответ Стефана для такого решения.
awk '{ print $2 " " $3 }' < input \
| cut -c1-16 \
| sort \
| uniq -c \
| awk '{ if ($1 > 60) print $2 }'
т.е. получить поля даты и времени, убрать секунды, отсортировать результат (NB: было бы лучше, если бы ваши даты были в формате ISO), найти количество каждой уникальной комбинации даты / времени, а затем распечатать их со счетчиком> 60
В идеале вам нужно попробовать обработать файл только один раз и сохранить в памяти как можно меньше. В awk
вы можете:
awk -v n=60 '
{
t = $2 substr($3, 1, 5);
if (t == last_t) {
if (++lines > n)
print
else
if (lines == n)
print saved $0
else
saved = saved $0 RS
} else {
saved = $0 RS
lines = 1
last_t = t
}
}' < your-file
Несколько преимуществ такого подхода:
tail -fn +1 log_file
). awk
), поэтому будет максимально эффективным. Противоположным крайним случаем было бы выполнение нескольких команд в цикле . Самая дорогостоящая вещь в сценариях оболочки - это, как правило, разветвление и выполнение команд. Оптимизация означает максимальное сокращение этого количества. Код awk
можно сделать очень разборчивым и понятным. Теперь, если размер имеет значение, вы также можете сделать его короче и на одной строке, например
awk '{t = $ 2substr ($ 3,1,5); if (t == l) {if (++ i> n) print; else if (i == n) print s $ 0; else s = s $ 0RS} else {s = $ 0RS; i = 1; l = t}} 'n = 60 файлов