首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在从管道读取输入时匹配Perl中的多行

如何在从管道读取输入时匹配Perl中的多行
EN

Stack Overflow用户
提问于 2015-08-05 22:37:24
回答 1查看 218关注 0票数 2

我想从日志文件中提取数据。该数据跨越多行。开始行包含一个时间戳、一个线程id和一些其他相关属性。结束行包含线程id和运行时间该线程忙碌的时间。将结果写入CVS文件进行统计分析。每个结果行应该如下所示:起始行的时间戳、线程id、其他相关属性和运行时间。

重新排列的日志片段如下所示:

代码语言:javascript
复制
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | Received message with id 1234 - com.example.product.module.Receiver#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #1 - com.example.product.module.Helper1#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #2 - com.example.product.module.Helper2#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #3 - com.example.product.module.Helper3#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #4 - com.example.product.module.Helper4#123
2015-08-01 12:23:21.224 | DEBUG | Thread-10 | Message processed in 101ms - com.example.product.module.Receiver#130

2015-08-01 12:24:21.123 | DEBUG | Thread-11 | Received message with id 2345 - com.example.product.module.Receiver#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | some log message #1 - com.example.product.module.Helper1#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | some log message #2 - com.example.product.module.Helper2#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | some log message #3 - com.example.product.module.Helper3#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | some log message #4 - com.example.product.module.Helper4#123
2015-08-01 12:24:21.225 | DEBUG | Thread-11 | Message processed in 102ms - com.example.product.module.Receiver#130

2015-08-01 12:25:21.123 | DEBUG | Thread-12 | Received message with id 3456 - com.example.product.module.Receiver#123
2015-08-01 12:25:21.123 | DEBUG | Thread-12 | some log message #1 - com.example.product.module.Helper1#123
2015-08-01 12:25:21.123 | DEBUG | Thread-12 | some log message #2 - com.example.product.module.Helper2#123
2015-08-01 12:25:21.123 | DEBUG | Thread-12 | some log message #3 - com.example.product.module.Helper3#123
2015-08-01 12:25:21.123 | DEBUG | Thread-12 | some log message #4 - com.example.product.module.Helper4#123
2015-08-01 12:25:21.226 | DEBUG | Thread-12 | Message processed in 103ms - com.example.product.module.Receiver#130

但在现实中,这些日志消息是混合的,因为应用程序同时运行多个线程。因此,实际日志如下所示:

代码语言:javascript
复制
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | Received message with id 1234 - com.example.product.module.Receiver#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #1 - com.example.product.module.Helper1#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #2 - com.example.product.module.Helper2#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | Received message with id 2345 - com.example.product.module.Receiver#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #3 - com.example.product.module.Helper3#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | some log message #1 - com.example.product.module.Helper1#123
2015-08-01 12:25:21.123 | DEBUG | Thread-12 | Received message with id 3456 - com.example.product.module.Receiver#123
2015-08-01 12:25:21.123 | DEBUG | Thread-12 | some log message #1 - com.example.product.module.Helper1#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | some log message #2 - com.example.product.module.Helper2#123
2015-08-01 12:25:21.123 | DEBUG | Thread-12 | some log message #2 - com.example.product.module.Helper2#123
2015-08-01 12:23:21.123 | DEBUG | Thread-10 | some log message #4 - com.example.product.module.Helper4#123
2015-08-01 12:24:21.123 | DEBUG | Thread-11 | some log message #3 - com.example.product.module.Helper3#123
2015-08-01 12:23:21.224 | DEBUG | Thread-10 | Message processed in 101ms - com.example.product.module.Receiver#130
2015-08-01 12:24:21.224 | DEBUG | Thread-11 | some log message #4 - com.example.product.module.Helper4#123
2015-08-01 12:25:21.224 | DEBUG | Thread-12 | some log message #3 - com.example.product.module.Helper3#123
2015-08-01 12:25:21.224 | DEBUG | Thread-12 | some log message #4 - com.example.product.module.Helper4#123
2015-08-01 12:24:21.225 | DEBUG | Thread-11 | Message processed in 102ms - com.example.product.module.Receiver#130
2015-08-01 12:25:21.226 | DEBUG | Thread-12 | Message processed in 103ms - com.example.product.module.Receiver#130

我制作了一个正则表达式,它能够在“重新排列”的日志上执行匹配:

代码语言:javascript
复制
/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}).*(Thread-\d+).*Received message with id (\d+) [\s\S]+?\2.*Message processed in (\d+)ms/g

打印捕获的组(print "$1;$2;$3;$4\n";)时所需的结果为:

代码语言:javascript
复制
2015-08-01 12:23:21.123;Thread-10;1234;101
2015-08-01 12:24:21.123;Thread-11;2345;102
2015-08-01 12:25:21.123;Thread-12;3456;103

当我使用www.regexr.com尝试这些示例时,对重新排列的日志片段的运行给出了三个匹配项。

我现在遇到的第一个问题是:当我想在Perl一行程序中使用正则表达式时,我无法在多行代码上执行匹配。我认为这与-n开关有关,该开关导致在perl代码周围添加循环,并且perl代码分别在每一行上执行。

cat files.log | perl -ne 'next LINE unless /(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}).*(Thread-\d+).*Received message with id (\d+) [\s\S]+?\2.*Message processed in (\d+)ms/gm; print "$1;$2;$3;$4\n";'

我面临的第二个问题是,在真实的日志文件中,日志文件排列得不是很好,我不能提取所有可能的匹配。在给定的截图中,只能匹配一个结果,而不是所有三个结果。

我尝试过将Perl命令中的记录分隔符设置为undef $\=undef;,删除next LINE unless...

谁能给我指个方向,或许能帮上忙?

日志文件可能会变得相当大(大约200MB),所以将所有行合并为一个巨大的字符串似乎不是一个好方法,尽管我还没有尝试过。

EN

回答 1

Stack Overflow用户

发布于 2015-08-05 23:00:15

散列通常用于分组。

代码语言:javascript
复制
my %buf;
while (<>) {
   chomp;
   my @fields = split / \| /;
   my $id = $fields[2];
   push @{ $buf{$id} }, \@fields;
   process(@{ delete($buf{$id}) })
      if $fields[3] =~ /^Message processed in /;
}

对每组行调用processprocess的每个参数都是一行,作为对字段数组的引用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31835600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档