Сравнение и анализ содержимого файлов
Имеем динамические логи, создаваемые ежечасно. Необходимо выявить 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
Ответы (5 шт):
Используйте grep:
grep -E '.*tear1.*092' $miss
С переменными:
grep -E ".*$var1.*$var2" $miss
У вас всегда логи, в которых пишутся пути указанного вида (уровень вложенности каталогов от корня 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
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 просто печатаем "Тревога !!!"
В общем вот, что получилось и это работает:
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
while read line; do
#2#Инициализируем строку для переменной path и file
source <(printf "$line")
#3#Печатаем срезая все лишнее
echo "${path/*\/} ${file/*.}"
#1#Находим все файлы измененные -24 часа и передаем в цикл для объявления переменных
done< <(find /home/tar/incoming/ -type f -mtime -1 -printf 'path="%h";file="%f"\n') | sort | uniq -dc
Не тестировал, так как сейчас не на чем.