我正在使用一个脚本将一堆内存值输出到日志文件中,我需要提取一些彼此相对的特定行。
以下是日志输出块的示例:
Pool ID Type Term User/Sys Total Size Free
------- ---- ---- -------- ---------- ----
0x7FC636000000 CONTROL LONG USER 1609564160 335224768
Client ID Memory Alloc'd (Normal/Small) Client Name
--------- -------------- -------------- -----------
0x7FC636001A90 7470051 (7469056/995) DiskControl
0x7FC6360017D8 4067072 (4067072/0) KJS
0x7FC636001520 1158242183 (1157640768/601415) PLU
0x7FC636001268 68499632 (68498240/1392) Splitter
0x7FC636000FB0 36665368 (36664256/1112) BackView
我需要提取PLU行:
0x7FC636001520 1158242183 (1157640768/601415) PLU
我还需要提取池ID
0x7FC636000000 CONTROL LONG USER 1609564160 335224768
这个块是其中之一,如果不知道客户端的位置,就无法确定要抓取哪个池ID(所以我需要在找到池之前找到PLU的第一个位置)。
找到PLU线很简单:
/(.*)PLU/
但事实证明找到泳池线要困难得多。
我发现使用多行正则表达式搜索的建议似乎没有用。我也尝试使用看起来不起作用的回顾。
暂时忽略与特定客户端和池的必要关系,我只针对池行尝试了这个:
/(?<=----).*(?=Client)/gm
这不会突出显示regexr上的任何内容。
如果有人能提供帮助,我会感激一些帮助。我正在使用Perl编写此脚本来提取信息(整个基础结构在Perl中)。
答案 0 :(得分:2)
将整个文件读入内存通常是一个坏主意,因为您通常需要将其拆分成行来处理它,您也可以在第一时间逐行读取它
如果我理解正确,您只需要存储您遇到的每个Pool ID。然后,当您找到PLU客户端时,相关的池ID是您遇到的最新版本
它看起来像这样
use strict;
use warnings 'all';
my ($pool_id, $client_id);
while ( <DATA> ) {
if ( /Pool ID/ ) {
while ( <DATA> ) {
last if ($pool_id) = /^0x(\p{hex}+)/;
}
}
elsif ( /\sPLU\s*$/) {
($client_id) = /^0x(\p{hex}+)/;
last;
}
}
print "Pool ID: $pool_id\n";
print "PLU Client ID: $client_id\n";
__DATA__
Pool ID Type Term User/Sys Total Size Free
------- ---- ---- -------- ---------- ----
0x7FC636000000 CONTROL LONG USER 1609564160 335224768
Client ID Memory Alloc'd (Normal/Small) Client Name
--------- -------------- -------------- -----------
0x7FC636001A90 7470051 (7469056/995) DiskControl
0x7FC6360017D8 4067072 (4067072/0) KJS
0x7FC636001520 1158242183 (1157640768/601415) PLU
0x7FC636001268 68499632 (68498240/1392) Splitter
0x7FC636000FB0 36665368 (36664256/1112) BackView
Pool ID: 7FC636000000
PLU Client ID: 7FC636001520