我们正在尝试编写一个脚本“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
答案1
使用以下内容计算两个时间变量之间的线。将以下代码放入名为的文件中 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
首先,我在尝试重现您的问题时遇到了 2 个错误
date: extra operand
11:34:14' Try
date --help' for more information.
./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 次出现,这看起来是正确的,因为应该排除第一个和最后一个日期。
因此,自纪元以来的秒数转换肯定在语法上存在错误,并且 if 语句中的 < 运算符造成了小混乱。
作为一般准则,对于 if,优先使用 -lt -gt(小于、大于)运算符。同时尽量避免将命令括在反引号中 - 优先使用 $(command)。
祝您编码愉快。