Вика Сорокина, вот такой, счёт по минуте:
LC_ALL=C rg -F 'timeout' progon.log | cut -c1-16 | uniq -c | sort -k1 -rn | head
Теперь важное, о чём почти никто не думает. Лог прогона отсортирован по времени, потому что пишется подряд. Значит по нему работает поиск делением пополам, и вместо гигабайта вы читаете сотню килобайт.
# найти байтовое смещение первой строки после 03:40
awk -v t="03:40" 'substr($0,12,5) >= t { print NR; exit }' progon.log
# и дальше работать куском
sed -n '4180000,4260000p' progon.log > kusok.log
С awk на гигабайте тоже долго, поэтому у себя я держу мелкий скрипт, который прыгает по файлу через seek, читает по строке и сужает границы. Гигабайт он проходит за двадцать шагов, это доли секунды.
И про хранение сразу: складывайте старое zstd, у него ratio на текстовых логах около десятки, а rg -z ищет прямо внутри сжатого. Гигабайт превращается в сотню мегабайт, поиск замедляется процентов на тридцать, места экономится вдесятеро.