在指定的时间范围内从日志文件中提取数据

我想使用基于时间范围的shell脚本(bash)从日志文件中提取信息。 日志文件中的一行如下所示:

172.16.0.3 - - [31/Mar/2002:19:30:41 +0200] "GET / HTTP/1.1" 200 123 "" "Mozilla/5.0 (compatible; Konqueror/2.2.2-2; Linux)" 

我想提取数据的具体时间间隔。 例如,我只需要查看最后logging的数据在最近X分钟或X天前发生的事件。 我是新的shell脚本,但我试图使用grep命令。

你可以使用sed 。 例如:

 $ sed -n '/Feb 23 13:55/,/Feb 23 14:00/p' /var/log/mail.log Feb 23 13:55:01 messagerie postfix/smtpd[20964]: connect from localhost[127.0.0.1] Feb 23 13:55:01 messagerie postfix/smtpd[20964]: lost connection after CONNECT from localhost[127.0.0.1] Feb 23 13:55:01 messagerie postfix/smtpd[20964]: disconnect from localhost[127.0.0.1] Feb 23 13:55:01 messagerie pop3d: Connection, ip=[::ffff:127.0.0.1] ... 

怎么运行的

-n开关告诉sed不输出它读取的每一行文件(默认行为)。

正则expression式之后的最后一个p指示它打印与前面的expression式匹配的行。

expression式'/pattern1/,/pattern2/'将会打印第一个模式和第二个模式之间的所有内容。 在这种情况下,它将打印它在stringFeb 23 13:55和stringFeb 23 14:00之间find的每一行。

更多信息在这里 。

使用grep和正则expression式,例如,如果您需要4分钟的日志间隔:

 grep "31/Mar/2002:19:3[1-5]" logfile 

将于2002年3月31日19时31分至19时35分之间返回所有日志。 假设您需要从今天27 / Sep / 2011开始的最后5天,您可以使用以下内容:

 grep "2[3-7]/Sep/2011" logfile 

好吧,我花了一些时间在你的date格式…..

不过,终于我解决了..

我们来看一个示例文件(名为logFile ),我做了一个简短的介绍。 说,你想得到最后5分钟的日志在这个文件中:

 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:20:41 +0200] "GET ### lines below are what you want (5 mins till the last record) 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:27:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:30:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:30:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:30:41 +0200] "GET 172.16.0.3 - - [31/Mar/2002:19:30:41 +0200] "GET 

这里是解决scheme:

 # this variable you could customize, important is convert to seconds. # eg 5days=$((5*24*3600)) x=$((5*60)) #here we take 5 mins as example # this line get the timestamp in seconds of last line of your logfile last=$(tail -n1 logFile|awk -F'[][]' '{ gsub(/\//," ",$2); sub(/:/," ",$2); "date +%s -d \""$2"\""|getline d; print d;}' ) #this awk will give you lines you needs: awk -F'[][]' -v last=$last -vx=$x '{ gsub(/\//," ",$2); sub(/:/," ",$2); "date +%s -d \""$2"\""|getline d; if (last-d<=x)print $0 }' logFile 

输出:

 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:27:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:30:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:30:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:30:41 +0200 "GET 172.16.0.3 - - 31 Mar 2002 19:30:41 +0200 "GET 

编辑

您可能会注意到在输出中[和]消失了。 如果你想让他们回来,你可以改变最后的awk行print $0 – > print $1 "[" $2 "]" $3

我使用这个命令来查找特定事件“ DHCPACK ”的最后5分钟日志,请尝试如下:

 $ grep "DHCPACK" /var/log/messages | grep "$(date +%h\ %d) [$(date --date='5 min ago' %H)-$(date +%H)]:*:*" 

您可以使用它获取当前和日志时间:

 #!/bin/bash log="log_file_name" while read line do current_hours=`date | awk 'BEGIN{FS="[ :]+"}; {print $4}'` current_minutes=`date | awk 'BEGIN{FS="[ :]+"}; {print $5}'` current_seconds=`date | awk 'BEGIN{FS="[ :]+"}; {print $6}'` log_file_hours=`echo $line | awk 'BEGIN{FS="[ [/:]+"}; {print $7}'` log_file_minutes=`echo $line | awk 'BEGIN{FS="[ [/:]+"}; {print $8}'` log_file_seconds=`echo $line | awk 'BEGIN{FS="[ [/:]+"}; {print $9}'` done < $log 

并比较log_file_*current_*variables。