脚本来计算给定时间间隔内特定string的出现次数

我们正在尝试编写一个脚本“sendemail.sh”来计算给定间隔内的日志文件“SendEmail.log”中特定string的出现次数。 我们有一个日志文件。 在这里,我们正在寻找一个模式“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 

使用以下内容计算两个时间variables之间的线。 将下面的代码放在一个名为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个错误,试图重新创build你的问题date: extra operand 11:34:14' Try date --help' for more information. ./script.sh: line 15: 1408448098: No such file or directory

根据我的理解,您根据用户input将您感兴趣的date隔离到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" 

将date更改为:

 startDate="2014-08-19 11:28:03" endDate="2014-08-19 11:34:58" sysadmin@omg:/tmp$ ./script.sh | wc 35 70 315 

返回35次,因为应该排除第一个和最后一个date,所以看起来是正确的。

所以,从Epoch开始,转换成秒数肯定是语法上有问题,if语句中的<运算符造成了一些小混乱。

由于一般的指导方针倾向于在if中使用-lt -gt(小于,大于)运算符。 还要尽量避免在反引号中包含命令 – 优先使用$(command)。

快乐的编码。