Perl Foreach直到循环

时间:2014-12-29 18:14:49

标签: perl

我的输出看起来像这样:

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)

1 个答案:

答案 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
}

但是你还没有解释你的目的,如果你不得不多做一次或两次或者列表很小,这样的循环是从列表中选择项目的低效​​方法。