我的输出看起来像这样:
Id: 214215
Time: 5:07
jName: Bar_Start
joutcome: warning
pName: Bar
jstatus: running
stepName Start:
outcome: success
status: completed
---End Step---
stepName A:
outcome: success
status: completed
---End Step---
stepName B:
outcome: success
status: completed
---End Step---
stepName C:
outcome: success
status: completed
---End Step---
stepName DC:
outcome: warning
status: completed
---End Step---
---------------END FINAL---------------
Id: 123456
Time: 11:08
jName: Foo_Start
joutcome: success
pName: Foo
jstatus: completed
stepName A:
outcome: success
status: completed
---End Step---
stepName AD:
outcome: success
status: completed
---End Step---
我想解析它,以便在" ---结束步骤---"之前的每一行。 包括标题存储在如下的散列中:
my %rowdata = (
Id => "214215",
Time => "5:07",
jName => "Bar_start",
jOutcome => "warning",
pName => "Bar",
jStatus => "running",
stepName => "Start",
outcome => "success",
status => "completed",
);
my %rowdata = (
Id => "214215",
Time => "5:07",
jName => "Bar_start",
jOutcome => "warning",
pName => "Bar",
jStatus => "running",
stepName => "A",
outcome => "success",
status => "completed",
);
my %rowdata = (
Id => "214215",
Time => "5:07",
jName => "Bar_start",
jOutcome => "warning",
pName => "Bar",
jStatus => "running",
stepName => "B",
outcome => "success",
status => "completed",
);
...
my %rowdata = (
Id => "123456",
Time => "11:08",
jName => "Foo_start",
jOutcome => "success",
pName => "Foo",
jStatus => "completed",
stepName => "A",
outcome => "success",
status => "completed",
);
我相信我需要做以下的事情来填充我的哈希:
foreach my $key (keys %rowdata) {
if ($row =~ m/\s*$key:.*/) {
$rowdata{$key} = $row;
}
}
但我不确定如何将标题分开一步,然后在到达时包含一个新标题--- END FINAL ---
然后我想迭代每个存储的哈希并根据当前条件做事。目前输出存储在一个数组(@rows)
中答案 0 :(得分:2)
看起来您只需要保留每个参数的最新值,并在每次出现---End Step---
时将一组值保存到列表中。
这个程序就是这样做的。我只使用Data::Dump
来证明结果数据结构是按照要求进行的。
请注意您的上一个输出记录会反映倒数第二个输入记录的内容。我已经使用您的示例数据生成此处显示的输出。
use strict;
use warnings;
open my $fh, '<', 'data.txt' or die $!;
my (@data, %rowdata);
while (<$fh>) {
if ( /^\s*(\w+) \s* : \s* (.*\S) /x or / \b (stepName) \s* (\w+) : /x ) {
$rowdata{$1} = $2;
}
elsif ( /---End Step---/ ) {
push @data, { %rowdata };
}
}
use Data::Dump;
dd \@data;
<强>输出强>
[
{
Id => 214215,
jName => "Bar_Start",
joutcome => "warning",
jstatus => "running",
outcome => "success",
pName => "Bar",
status => "completed",
stepName => "Start",
Time => "5:07",
},
{
Id => 214215,
jName => "Bar_Start",
joutcome => "warning",
jstatus => "running",
outcome => "success",
pName => "Bar",
status => "completed",
stepName => "A",
Time => "5:07",
},
{
Id => 214215,
jName => "Bar_Start",
joutcome => "warning",
jstatus => "running",
outcome => "success",
pName => "Bar",
status => "completed",
stepName => "B",
Time => "5:07",
},
{
Id => 214215,
jName => "Bar_Start",
joutcome => "warning",
jstatus => "running",
outcome => "success",
pName => "Bar",
status => "completed",
stepName => "C",
Time => "5:07",
},
{
Id => 214215,
jName => "Bar_Start",
joutcome => "warning",
jstatus => "running",
outcome => "warning",
pName => "Bar",
status => "completed",
stepName => "DC",
Time => "5:07",
},
{
Id => 123456,
jName => "Foo_Start",
joutcome => "success",
jstatus => "completed",
outcome => "success",
pName => "Foo",
status => "completed",
stepName => "A",
Time => "11:08",
},
{
Id => 123456,
jName => "Foo_Start",
joutcome => "success",
jstatus => "completed",
outcome => "success",
pName => "Foo",
status => "completed",
stepName => "AD",
Time => "11:08",
},
]
<强>更新强>
What would be the appropriate call to an array such as this?
If I wanted to do a `foreach` loop of it, would it be something like
foreach %key (@data) {
if (key{jName} =~ Foo_start) {
#then do this
}
}
我想我可能会因为建议您在%rowdata
每次出现时复制并存储---End Step---
的内容而犯了错误。如果您只需按顺序处理数据,那么最好通过撰写process_rowdata(\%rowdata)
代替push @data, { %rowdata }
来提供服务。
然而,问题的直接答案是您可以使用
迭代@data
for my $rowdata (@data) {
next unless $rowdata->{jName} eq 'Foo_start';
# Do stuff with $rowdata
}
但是你还没有解释你的目的,如果你不得不多做一次或两次或者列表很小,这样的循环是从列表中选择项目的低效方法。