【问题标题】:Perl: Adding to an array of a hashPerl:添加到哈希数组
【发布时间】:2013-10-14 06:49:01
【问题描述】:

我正在尝试将值添加到散列中的数组。

foreach my $f (@files) {
  my $file = "$logDir/$f";
  open my $info, $file or die "Could not open $file: $!";
  while (my $line = <$info>) {
    chomp $line;
    if ($line =~ /CONN.*\[ID=(.*)\].*ID is(.*)/) {
      $b = $1;
      $a = $2;
      $a =~ s/^\s+//;
      $bHash{$b} = $a if (exists $aHash{$a});
    }
    elsif ($line =~ /succ.*\[ID=(.*)\].*/) {
      $b = $1;
      push(@{ $bHash{$b} }, "bSUCC") if (exists $bHash{$b});
    }
    elsif ($line =~ /fail.*\[ID=(.*)\].*/) {
      $b = $1;
      push(@{ $bHash{$b} }, "bFAIL") if (exists $bHash{$b});
    }
  }
  close $info;
}

我根据 a 的事务 id 和 b 的事务 id 将两个日志文件链接在一起,这两个文件都位于 b 的日志中的单个日志行中。

第一个if 语句检查它,并用b->ID = a->Id 填充%bHash

然后我正在寻找 b 的交易是成功还是失败。如果我看到一条成功行,我将获取事务 ID,如果该 ID 存在于%bHash 中,那么我想将“bSucc”消息推送到数组的末尾,即%bHash 将具有 bSid -> aSid, bSucc .

我收到以下错误/警告消息:

Can't use string ("7747395") as an ARRAY ref while "strict refs" in use at ./report.pl line 54, <$info> line 833.

有没有办法做到这一点?

如果可能,我还想继续向数组添加信息,因为我会扫描日志以获取更多数据。我想使用事务 ID 作为密钥,并根据需要添加信息。这可能吗?有没有更好的方法来完成任务?

编辑:我想要完成的是跨 3 个不同的日志文件编译有关事务的信息。我想为每个事务找到以下内容:失败的成功,如果失败,它在哪里失败,在日志 a、b 或 c 中?

一个事务由 3 个不同的应用程序处理,因此有 3 个不同的日志。不幸的是,应用程序 a 与应用程序 b 和 c 中的 trans id 不同。所以我用 log a 中的所有 trans id 构建了一个哈希,然后在 log b 中有一个 log 行,它允许您查看用于 log a 的 trans id 和用于 log b 的 trans id 之间的链接。这就是为什么我将来自 b 的 trans id 与来自 log a 的哈希进行匹配。最终我想要上面提到的每个 transId 的信息,成功/失败等。

【问题讨论】:

  • 这根本行不通,因为您正在将$bHash{$b} 初始化为 A 事务 ID,然后尝试将其推入它,就好像它是一个数组引用一样。请显示您的数据文件的格式并准确描述您需要做什么。看起来这确实属于数据库。
  • 请学习正确地格式化您的 Perl,尤其是在提出相关问题之前。此外,你绝不能将$a$b 用作通用变量,首先因为它们根本不是描述性的(同样的原因你不应该调用散列%bHash)其次因为它们是Perl 内部使用,您可能会遇到访问冲突。
  • 添加了一些关于我存储信息的最终目标的细节。

标签: arrays perl hash


【解决方案1】:

问题在于,当您最初设置 %bHash 中的每个值时,您将其设置为字符串值,而不是 arrayref:

      $bHash{$b} = $a if (exists $aHash{$a});

稍后,您尝试通过取消引用将值推送到“数组”:

      push(@{ $bHash{$b} }, "bSUCC") if (exists $bHash{$b});

但是由于 is 没有数组,只有一个字符串,Perl 认为您正试图将字符串取消引用到一个数组中。 (我应该指出,这实际上是可能合法的——如果$a 是字符串'foo',那么@$a 表示全局变量@foo——但不建议这样做,不允许在use strict 的范围内,显然不是你想要做的。我提到它只是因为错误消息的文本认为这是你想要使用的功能。)

解决方法是简单地使用 arrayref 开头:

      $bHash{$b} = [$a] if (exists $aHash{$a});

这样您就有了一个可以安全地将值推送到其中的数组。

【讨论】:

  • 谢谢!效果很好,现在我可以将 id 和 succ/fail 添加到数组中。
猜你喜欢
  • 2020-06-30
  • 2021-05-06
  • 1970-01-01
  • 2020-12-08
  • 2022-07-21
  • 2012-09-03
  • 2012-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多