Skip to content

Instantly share code, notes, and snippets.

@sdlab1
Created September 10, 2025 13:01
Show Gist options
  • Select an option

  • Save sdlab1/cbdf542407fd622f3a34a46b6c705bb4 to your computer and use it in GitHub Desktop.

Select an option

Save sdlab1/cbdf542407fd622f3a34a46b6c705bb4 to your computer and use it in GitHub Desktop.
bash hash check
#!/bin/bash
LOG="fixlog.txt"
NOW=$(date +%s)
TODAY=$(date +%Y-%m-%d)
ONE_HOUR_AGO=$((NOW - 3600))
ONE_DAY_AGO=$((NOW - 86400))
# Ассоциативные массивы для подсчета и хранения времени
declare -A all_hash_counts
declare -A hash_last_timestamp
# Массивы для хранения порядка и принадлежности к временным группам
order_list=() # Список хэшей в порядке появления (без дубликатов)
declare -A in_order_set # Множество для отслеживания, добавлен ли хэш в order_list
# Массивы для временных групп (хранят хэши как ключи ассоциативных массивов)
declare -A today_set
declare -A last_24h_set
declare -A last_hour_set
# Переменная для хранения времени последнего обработанного хэша
previous_timestamp=0
# Счетчик для визуальной обратной связи
line_counter=0
# --- Функция для парсинга даты из строки ---
parse_date_time() {
local line="$1"
local datetime_str=""
local timestamp=""
# Проверяем формат: 10.Sep 07:54 FIX_cc4ea ... или 09.Sep 01:17 58683 ...
if [[ $line =~ ^([0-9]{1,2})\.(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\ ([0-9]{2}:[0-9]{2}) ]]; then
local day="${BASH_REMATCH[1]}"
local month="${BASH_REMATCH[2]}"
local time="${BASH_REMATCH[3]}"
datetime_str="$day $month $(date +%Y) $time"
# Проверяем формат: ;2025-09-08 12:23:37 или 2025-09-08 12:23:37
elif [[ $line =~ ^(;?)([0-9]{4}-[0-9]{2}-[0-9]{2}\ [0-9]{2}:[0-9]{2}:[0-9]{2}) ]]; then
datetime_str="${BASH_REMATCH[2]}"
# Проверяем формат: Mon Sep 8 14:15:29 EEST 2025
elif [[ $line =~ ^([A-Z][a-z]{2}\ [A-Z][a-z]{2}\ +[0-9]{1,2}\ [0-9]{2}:[0-9]{2}:[0-9]{2}\ [A-Z]{3,4}\ [0-9]{4}) ]]; then
datetime_str="${BASH_REMATCH[1]}"
# Проверяем формат: 08.09 14:25
elif [[ $line =~ ^([0-9]{2}\.[0-9]{2})\ ([0-9]{2}:[0-9]{2}) ]]; then
local date_part="${BASH_REMATCH[1]}"
local time_part="${BASH_REMATCH[2]}"
datetime_str="$(date +%Y)-${date_part:3:2}-${date_part:0:2} $time_part:00"
fi
if [[ -n "$datetime_str" ]]; then
timestamp=$(date -d "$datetime_str" +%s 2>/dev/null)
fi
echo "$timestamp"
}
# --- Функция для извлечения хэша из строки ---
extract_hash() {
local line="$1"
local hash=""
# Ищем 5-символьный шестнадцатеричный хэш
# Сначала пробуем формат с FIX_
if [[ $line =~ [Ff][Ii][Xx]_([a-fA-F0-9]{5}) ]]; then
hash="${BASH_REMATCH[1],,}" # Преобразуем в нижний регистр
# Потом пробуем формат с пробелом перед хэшем в конце (и не зафиксированный пробелом FIX_)
elif [[ $line =~ \ ([a-fA-F0-9]{5})(\ |$) ]] && [[ ! $line =~ [Ff][Ii][Xx]_[a-fA-F0-9]{5} ]]; then
hash="${BASH_REMATCH[1],,}"
fi
echo "$hash"
}
# --- Основной цикл обработки файла ---
while IFS= read -r line || [[ -n "$line" ]]; do
# Увеличиваем счетчик строк
((line_counter++))
# Каждые 20 строк выводим точку
if (( line_counter % 20 == 0 )); then
printf "." >&2
fi
timestamp=$(parse_date_time "$line")
if [[ -z "$timestamp" ]]; then
continue
fi
hash=$(extract_hash "$line")
if [[ -z "$hash" ]]; then
continue
fi
# --- Проверка хронологии ---
# Если текущий timestamp меньше предыдущего, это нарушение порядка
# Сохраняем эту информацию в ассоциативном массиве
if [[ $previous_timestamp -ne 0 && $timestamp -lt $previous_timestamp ]]; then
# Помечаем хэш как нарушающий хронологию
# Используем префикс для ключа, чтобы не конфликтовать с другими данными
declare -A chrono_check
chrono_check["out_of_order_$hash"]=1
fi
# Обновляем previous_timestamp для следующей итерации
previous_timestamp=$timestamp
# --------------------------
# Обновляем счетчики и время
if [[ -z "${all_hash_counts[$hash]}" ]]; then
all_hash_counts[$hash]=1
else
all_hash_counts[$hash]=$((all_hash_counts[$hash] + 1))
fi
hash_last_timestamp[$hash]=$timestamp
# Добавляем в список порядка (если еще не добавлен)
if [[ -z "${in_order_set[$hash]}" ]]; then
order_list+=("$hash")
in_order_set[$hash]=1
fi
# Проверяем временные интервалы
if [[ $timestamp -ge $ONE_DAY_AGO ]]; then
last_24h_set["$hash"]=1
hash_date=$(date -d "@$timestamp" +%Y-%m-%d 2>/dev/null)
if [[ "$hash_date" == "$TODAY" ]]; then
today_set["$hash"]=1
fi
if [[ $timestamp -ge $ONE_HOUR_AGO ]]; then
last_hour_set["$hash"]=1
fi
fi
done < "$LOG"
# Выводим новую строку после точек
echo >&2
# --- Вывод результатов ---
echo "=== АНАЛИЗ ХЭШЕЙ ФИКСОВ ==="
echo
i=0
for hash in "${order_list[@]}"; do
color=""
bg_color=""
# Определяем цвет фона по времени
if [[ ${last_hour_set[$hash]} ]]; then
bg_color="\033[48;2;40;0;80m" # светлый фиолетовый для последнего часа
elif [[ ${last_24h_set[$hash]} ]]; then
bg_color="\033[48;2;30;0;60m" # темно-синий/темно-фиолетовый для последних 24 часов
fi
# --- Проверка на нарушение хронологии ---
# Если хэш помечен как нарушающий порядок, перекрываем цвет текста
if [[ ${chrono_check["out_of_order_$hash"]} ]]; then
color="\033[32m" # Темно-зеленый для хэшей вне хронологии
else
# Определяем цвет текста по умолчанию
if [[ ${all_hash_counts[$hash]} -gt 1 ]]; then
color="\033[31m" # красный для дубликатов
else
color="\033[37m" # белый для уникальных
fi
fi
# ------------------------------------------
printf "${bg_color}${color}%s\033[0m " "$hash"
((i++))
if (( i % 9 == 0 )); then
echo
fi
done
if (( i % 9 != 0 )); then
echo
fi
echo
echo "=== СТАТИСТИКА ==="
echo "Всего хэшей: ${#order_list[@]}"
echo "Хэшей за последние 24 часа: ${#last_24h_set[@]}"
echo "Хэшей за последний час: ${#last_hour_set[@]}"
echo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment