bash脚本,打印与特定模式匹配的多行

时间:2013-12-04 13:09:19

标签: regex bash sed multiline

我有一个日志文件,我正在编写一个脚本来执行某些操作。操作是打印日志的特定区域。

 03:19:13.4 End summary update for ads.doc.ordered.OrderDetailSummary
 03:19:13.4 Begin summary update for ads.doc.inventory.InventoryItemSummary
 03:19:33.9 CronServer:: DailyJob ads.tools.UpdateSummaries@17c5d6cf failed with exception
  ads.util.AppError: Cannot create UnitName from keys: Each
  ads.util.AppError: Cannot create UnitName from keys: Each
  .....
  .....
  .....
  .....
 03:46:42.5 Periodic support request failed: ads.support.SupportException: Error opening socket: java.net.ConnectException: Connection refused
 06:31:36.1 Upload failed: java.io.FileNotFoundException: c:/tmp/cygwin1.dll (No such file or directory)
 08:01:08.0 connect from /172.22.3.28

OR

06:14:27.9 starting web server
06:14:33.3 Initializing Spring framework Logs
Oct 18, 2013 6:14:33 AM org.apache.catalina.startup.Embedded start
INFO: Starting tomcat server
Oct 18, 2013 6:14:34 AM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.32
Oct 18, 2013 6:14:35 AM org.apache.catalina.startup.ContextConfig defaultWebConfig
INFO: No default web.xml
Oct 18, 2013 6:14:38 AM org.apache.catalina.session.StandardManager doLoad
SEVERE: IOException while loading persisted sessions: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: ads.doc.backoffice.StoreInfos
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: ads.doc.backoffice.StoreInfos
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1354)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1915)
......
......
......
......

    at ads.tools.AppServerMain.main(AppServerMain.java:83)
Caused by: java.io.NotSerializableException: ads.doc.backoffice.StoreInfos
INFO: Jk running ID=0 time=0/105  config=null
06:14:48.6 Starting exporter server
06:14:48.6 starting cron server

我想打印包含单词exception的块。从时间戳到下一个时间戳

e.g1

03:19:33.9 CronServer:: DailyJob ads.tools.UpdateSummaries@17c5d6cf failed with exception ads.util.AppError: Cannot create UnitName from keys: Each
ads.util.AppError: Cannot create UnitName from keys: Each
.....
.....
.....
.....

以及下一个时间戳,如果它更容易。

OR

e.g2

06:14:33.3 Initializing Spring framework Logs
......
......
......

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: ads.doc.backoffice.StoreInfos
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1354)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1915)
......
......
......
......

    at ads.tools.AppServerMain.main(AppServerMain.java:83)
Caused by: java.io.NotSerializableException: ads.doc.backoffice.StoreInfos
INFO: Jk running ID=0 time=0/105  config=null
06:14:48.6 Starting exporter server

有没有办法用sed做到这一点?或任何其他想法,因为我真的很困惑。

据我所知,sed一次处理一行。

考虑搜索一行是否以此模式开头

^[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}.[0-9]

然后与异常字匹配,在下一行再次匹配表达式后打印所有这个块。

4 个答案:

答案 0 :(得分:0)

关键线似乎不是以日期开头,因此您可以搜索错误条件或不以这样的日期开头的行:

egrep -i "exception|^\s" yourlog

其中“\ s”是一个空格。

或者,不以数字开头的行:

egrep -i "exception|^[^0-9]"

答案 1 :(得分:0)

你可以说:

sed '/exception/,/^[0-9][0-9]/!d' filename

对于您的输入,它会返回:

03:19:33.9 CronServer:: DailyJob ads.tools.UpdateSummaries@17c5d6cf failed with exception
ads.util.AppError: Cannot create UnitName from keys: Each
ads.util.AppError: Cannot create UnitName from keys: Each
.....
.....
.....
.....
03:46:42.5 Periodic support request failed: ads.support.SupportException: Error opening socket: java.net.ConnectException: Connection refused

编辑:对于您的更新问题,以下内容可能对您有用:

sed -n -e :t -e '/^[0-9]/,/^[0-9]/{/^[0-9]/!{$!{N;bt}};/[Ex]xception/p;}' inputfile

答案 2 :(得分:0)

 perl -n -e 'if ( $_ =~ /^ \d{2}:\d{2}:\d{2}\.\d/ ) { $print = 0; } if ($print || $_ =~ /exception/) { print "$_"; $print = 1 };

这样的东西应该是perl替代品。

cat file.txt | perl ...

一样使用

答案 3 :(得分:0)

Sed的模式范围为:http://www.grymoire.com/Unix/Sed.html#uh-29

所以你可以这样做:

 sed -n '/AppError/,/^ *[0-9]\{1,2\}:[0-9]\{1,2\}:[0-9]\{1,2\}\.[0-9]/ p' file.log

-n ...除非您明确打印,否则禁止打印 您可以根据自己的喜好细化起始模式。

在你的结束模式中,你需要逃避花括号。