Сравнение и анализ содержимого файлов

Рейтинг: 0Ответов: 4Опубликовано: 06.03.2023

Имеем динамические логи, создаваемые ежечасно. Необходимо выявить 6 одинаковых пар значений (из последних 6 логов). Например: tear11 и 092 (то, что до точки анализировать нужно, т.к. это значение меняется постоянно) Логи выглядят так:

/home/tar/incoming/mear2/23030107.090
/home/tar/incoming/tear11/23030107.092
/home/tar/incoming/ear10/23030107.092

Я так понимаю, что строки надо разбить на массивы, но не совсем понятно как быть с последними 3 цифрами. На данный момент реализован сбор содержимого последних 6 логов в один файл output.txt. В нём полный путь до самого лога и содержимое.

miss=$(ls -1t /var/log/miss/*.miss | head -6)
cat /dev/null > output.txt
for file in $miss; do
  echo "$file" >> output.txt
     cat "$file" >> output.txt
    echo "" >> output.txt
done

С помощью sed можно напечатать по отдельности tear11 и 092 Как соединить воедино данную конструкцию?

    echo "/home/tar/incoming/tear11/23030107.092" | sed 's/.*\/\([^/]*\)\/\([^/]*\)$/\1/'
tear11

    echo "/home/tar/incoming/tear11/23030107.092" | sed 's/.*\(...\)$/\1/'
092

Ответы

▲ 0

Используйте grep:

grep -E '.*tear1.*092' $miss

С переменными:

grep -E ".*$var1.*$var2" $miss
▲ 0

У вас всегда логи, в которых пишутся пути указанного вида (уровень вложенности каталогов от корня 4)?

И вас интересует более одного совпадения последних значений? Если я вас правильно понял, то можно вот так вычислить все вхождения последнего элемента, больше одного в файл test.log вида:

/home/tar/incoming/mear2/23030107.090
/home/tar/incoming/tear11/23030107.092
/home/tar/incoming/ear10/23030107.092


$ cat test.log | cut -d "/" -f 6 | sort | uniq -c | grep -E "\s([2-9]|[1-9][0-9]+)\s"

результат:

  2 23030107.092

два вхождения для 23030107.092

▲ 0
find /home/tar/incoming -type f -printf "%T@ %p\n" \
     |sort -n |tail -6 |cut -d " " -f 2- \
     |awk -F'[/.]' 'NR==1{z1=$(NF-2)" "$NF;N=1} NR!=1{z=$(NF-2)" "$NF;if(z1 != z) exit;N++}END{if(N==6) print "Тревога !!!"}'

find ищет все файлы в указанной папке и выводит их в виде двух составляющих, первое это unixtime последнего изменения файла и второе это путь к файлу.

sort сортирует по времени(первый столбец), tail обрезает последние шесть строк где находятся нужные нам записи, а после с помощью утилиты cut вырезаем первый столбец оставляя тока путь.

дале указываем awk разделители - косую черту(/) и точку(.), после чего запоминаем в переменную последнее и второе с конца поле, эту переменную затем последовательно сравниваем с остальными значениями и при первом же несовпадении выходим(exit), если же значения во всех шести строках совпали то по окончании работы awk просто печатаем "Тревога !!!"

▲ 0

В общем вот, что получилось и это работает:

miss=$(ls -1t /var/log/miss/*.miss | head -5)
cat /dev/null > /opt/output
for file in $miss; do
#     echo "$file" >> /opt/output
cat "$file" >> /opt/output
echo "" | grep -Ev "^$" >> /opt/output
done
sed 's/.*\/\([^\/]*\)\/[^\/]*\.\([^\/]*\)/\1 \2/' /opt/output |sort |uniq -dc |sed 's/^[ \t]*//' > /opt/channels

И на выходе имеем в файле /opt/channels:

5 mear2 090
4 tear11 092
4 ear10 092