Скрипт для подсчета появления конкретной строки в заданном интервале времени
Мы пытаемся написать скрипт "sendemail.sh" для подсчета количества вхождений определенной строки в файл журнала "SendEmail.log" в течение заданного интервала. У нас есть файл журнала. Так как мы ищем шаблон "ReqInputMsgLog" и нам необходимо подсчитать, сколько раз он произошел за указанный период, например: от "2014-08-19 11:30" до "2014-08-19 11:34", И наш скрипт выглядит так:
#!/bin/sh
enterdate=$1
echo $enterdate
enddate=$2
enterdate1=`date +%s -d $enterdate +"%Y-%m-%d %H:%M"`
echo $enterdate1
enddate1=`date +%s -d $enddate +"%Y-%m-%d %H:%M"`
echo $enddate
count=0
cat SendEmail.log | grep "ReqInputMsgLog" | awk -F "[" '{print $3}' | awk -F "," '{print $1}' > /con/scripts_server/file.txt
for line in `cat /con/scripts_server/file.txt`
do
logdate=`echo $line | awk -F : '{print $1":"$2}'`
if [[ $logdate < $enddate1 ]];
then
count=`expr $count + 1`
fi
done
echo $count
Но когда мы пытаемся выполнить скрипт с помощью приведенной ниже команды, он не показывает правильное количество.
./sendemail.sh "2014-08-19 11:30" "2014-08-19 11:34"
Файл журнала очень большой. Небольшой кусок был размещен здесь.
INFO [SIBJMSRAThreadPool : 5] [2014-08-19 11:18:24,471] SendEmail - 8/19/14 11:18 AM,ECCF25B0-0147-4000-E000-1B830A3C05A9,ReqInputMsgLog,SendEmail,<?xml version="1.0" encoding="UTF-8"?>
<in:sendEmailRequestMsg xmlns:in="http://EmailMed/EmailMedInterface" xmlns:ns0="wsdl.http://EmailMed/EmailMedInterface" xmlns:ns1="http://EmailMed/EmailMedInterface" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:me="wsdl.http://EmailMed/EmailMedInterface" xsi:type="me:sendEmailRequestMsg">
<in:sendEmail xmlns:xci0="http://EmailMed/EmailMedInterface">
INFO [SIBJMSRAThreadPool : 7] [2014-08-19 11:18:14,235] SendEmail - 8/19/14 11:18 AM,ECCEFDB2-0147-4000-E000-1B830A3C05A9,ReqInputMsgLog,SendEmail,<?xml version="1.0" encoding="UTF-8"?>
<in:sendEmailRequestMsg xmlns:in="http://EmailMed/EmailMedInterface" xmlns:ns0="wsdl.http://EmailMed/EmailMedInterface" xmlns:ns1="http://EmailMed/EmailMedInterface" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:me="wsdl.http://EmailMed/EmailMedInterface" xsi:type="me:sendEmailRequestMsg">
<in:sendEmail xmlns:xci0="http://EmailMed/EmailMedInterface">
INFO [SIBJMSRAThreadPool : 7] [2014-08-19 11:18:14,241] SendEmail - xmlText: <?xml version="1.0" encoding="UTF-8"?>
после команды awk мы получим файл "/con/scripts_server/file.txt", который выглядит примерно так:
2014-08-19 11:28:03
2014-08-19 11:28:06
2014-08-19 11:28:17
2014-08-19 11:28:53
2014-08-19 11:29:02
2014-08-19 11:29:47
2014-08-19 11:29:57
2014-08-19 11:30:07
2014-08-19 11:30:17
2014-08-19 11:30:19
2014-08-19 11:30:19
2014-08-19 11:30:22
2014-08-19 11:30:25
2014-08-19 11:30:25
2014-08-19 11:30:36
2014-08-19 11:30:51
2014-08-19 11:30:56
2014-08-19 11:30:59
2014-08-19 11:30:59
2014-08-19 11:31:08
2014-08-19 11:31:25
2014-08-19 11:32:19
2014-08-19 11:32:22
2014-08-19 11:32:27
2014-08-19 11:32:28
2014-08-19 11:32:41
2014-08-19 11:32:49
2014-08-19 11:32:59
2014-08-19 11:33:27
2014-08-19 11:33:41
2014-08-19 11:34:07
2014-08-19 11:34:14
2014-08-19 11:34:21
2014-08-19 11:34:25
2014-08-19 11:34:38
2014-08-19 11:34:50
2014-08-19 11:34:58
2 ответа
Используйте следующее, чтобы вычислить линии между двумя временными переменными. Поместите следующий код в файл с именем countOcurrences
,
#!/bin/bash
awk "/$1/,/$2/"'{count++} END{ printf "There are %s lines\n", count}' con/scripts_server/file.txt
Запустите его следующим образом.
./countOcurrences "2014-08-19 11:30:07" "2014-08-19 11:34:07"
Если file.txt
заполнен новым date/time
каждый раз, когда происходит сопоставление с шаблоном, вышеописанное будет работать.
Прежде всего я столкнулся с 2 ошибками, пытаясь воссоздать вашу проблему
date: extra operand
11:34:14'
Try
date --help'для получения дополнительной информации.
./script.sh: line 15: 1408448098: No such file or directory
Из того, что я понимаю, вы выделили даты, которые вас интересуют, в file.txt в соответствии с пользовательским вводом, и вы хотите посчитать в нем вхождения.
Я закодировал это:
#!/bin/bash
#Start/End dates to encolse count range
startDate="2014-08-19 11:28:00"
endDate="2014-08-19 11:35:00"
#Concert these dates to seconds since Epoch
startDateEpoch=$(date --date="$startDate" +%s)
endDateEpoch=$(date --date="$endDate" +%s)
#Read file.txt count occurences
while read line
do
processingDate=$(date --date="$line" +%s)
if [ $processingDate -lt $endDateEpoch ] && \
[ $processingDate -gt $startDateEpoch ]; then
echo "APOEL FC";
fi
done < file.txt
Ваш файл file.txt в приложении содержит 37 строк, поэтому:
sysadmin@omg:/tmp$ ./script.sh | wc
37 74 333
Это выглядит правильно для
startDate="2014-08-19 11:28:00"
endDate="2014-08-19 11:35:00"
Изменение даты на:
startDate="2014-08-19 11:28:03"
endDate="2014-08-19 11:34:58"
sysadmin@omg:/tmp$ ./script.sh | wc
35 70 315
возвращает 35 вхождений, которые выглядят корректно, поскольку первая и последняя даты должны быть исключены.
Таким образом, преобразование в секунды со времени Epoch должно было иметь что-то неправильное в синтаксисе, а оператор <в вашем операторе if вызывал небольшой беспорядок.
Поскольку общие рекомендации предпочитают использовать операторы -lt -gt (меньше чем, больше чем) для if. Также старайтесь избегать включения команды в backticks - Предпочитаю использовать $(command).
Удачного кодирования.