【问题标题】:Auto increment hash value retrieval自动递增哈希值检索
【发布时间】:2014-08-29 09:33:00
【问题描述】:

我有一个 perl 脚本可以远程登录到一些网络设备,运行一个命令来收集一些卡信息并将每一行返回到一个数组中,然后我将它映射到一个哈希中。我要做的是执行一个正则表达式来获取哈希中每个字符串值开头的卡号并将它们推送到一个数组中。但是,只有一半……因为设备中的每张卡在输出中都会加倍,因为供应商在命令后返回信息的方式。

下面是@output,运行命令后看到的输出。

1/1  1187100L1  , Combo A2+ AE.
1/4  1187100L2  , Combo A2+ K.
1/5  1187100L1  , Combo A2+ V
1/16 1187100L2  , Combo A2+ K
1/1  1187100L1  , Combo A2+ No Alarms
1/4  1187100L2  , Combo A2+ No Alarms
1/5  1187100L1  , Combo A2+ No Alarms
1/16 1187100L2  , Combo A2+ No Alarms

有一部分将@output 数组的标量值除以一半。我想要做的是执行 $hash{} 检索并自动增加标量 /2 的数量。

我只想检索前 4 个卡号,1/1、1/4、1/5 和 1/16。

有什么建议吗?

这是我需要帮助的代码部分:

if (@output) {
    @ccl = grep ( /Combo/, @output );
    my %hash = map { ++$shn => $_ } @ccl;
    my $an = scalar(@ccl) / 2;
    if ( $hash{0} =~ /^(\d+\/\d+)/ ) {
        push( @numbers, $1 );
        print "@numbers\n";
    }
}

上述工作正常,但仅适用于哈希中的第一个值。我只想对哈希中的一半值运行它。

【问题讨论】:

  • “自动增量”是什么意思?我知道该术语的唯一用途是在数据库中,当您插入行时,会自动为 ID 列分配递增值。它与简单地增加哈希值有什么不同?
  • 在您的代码中,您永远不会使用变量$an。这不是你说要在自动增量中使用的吗?
  • 确切地说,它是我想要自动增加哈希值的变量 $an,在这种情况下恰好是数字 4。但我不知道如何在 $hash{} 中的 {} 之间应用它。我所说的自动增量是指能够在一行中写下以下几行:$hash{0} $hash{1 } $hash{3} $hash{4} 自动基于 $an 中的数字。如果我做 $hash{$an} 它只是意味着 $hash{4}。我希望它在 $an 中多次执行该命令。
  • 还是不明白你的意思。哈希值是字符串,而不是数字,因此增加它们是没有意义的。
  • 不是值本身,而是值的数量。

标签: arrays regex perl hash


【解决方案1】:

这将为哈希值的前半部分运行您的代码。

foreach my $i (0 .. $an-1) {
    if ( $hash{$i} =~ /^(\d+\/\d+)/ ) {
        push( @numbers, $1 );
    }
}
print "@numbers\n";

顺便说一句,通过将递增数字映射到值来创建哈希似乎很奇怪。那本质上是一个数组,那为什么不直接使用数组呢?

【讨论】:

  • 我把它放到了一个散列中,这样我就可以对标量值使用一个正则表达式,因为通过一个数组进行 grepping 不会只返回我搜索的模式,而是整个行。既然你提到了它,我很可能只用一个数组来做它,比如 '$array[0]' 或其他东西。我运行了上面的代码,它运行了循环,但是将匹配的模式推到数组的末尾 4 次,就像这样 '1/1 1/1 1/4 1/1 1/4 1/5 1/1 1/4 1 /5 1/16'
  • 我宁愿只返回每组数字一次,因为在此之后,我将根据这些数字运行另一个命令,以获取每张卡上的单独统计信息,然后存储在数据库中。它按原样工作正常,但最终返回的数据加倍。
  • 您每次都通过循环打印数组。所以你会看到它的成长。也许您应该将print 语句移到循环之外。
  • 如果你有一个完全不同的方式让我写整个事情,我完全赞成。随意将其切碎并送回。
  • 您只是被调试语句弄糊涂了。如果我理解你,结果正是你想要的。
【解决方案2】:

从您所写的内容来看,我认为这就是您想要的。它从每一行中提取卡号并使用%seen 哈希将其推送到@numbers(如果它是第一次出现)。

use strict;
use warnings;

my @output = <DATA>;

my @numbers;
my %seen;
for (@output) {
   next unless /Combo/i;
   my ($card) = /(\S+)/;
   push @numbers, $card unless $seen{$card}++;
}

use Data::Dump;
dd \@numbers;

__DATA__
1/1  1187100L1  , Combo A2+ AE.
1/4  1187100L2  , Combo A2+ K.
1/5  1187100L1  , Combo A2+ V
1/16 1187100L2  , Combo A2+ K
1/1  1187100L1  , Combo A2+ No Alarms
1/4  1187100L2  , Combo A2+ No Alarms
1/5  1187100L1  , Combo A2+ No Alarms
1/16 1187100L2  , Combo A2+ No Alarms

输出

["1/1", "1/4", "1/5", "1/16"]

【讨论】:

    猜你喜欢
    • 2018-02-28
    • 2017-06-10
    • 2013-01-27
    • 2014-01-02
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    • 2014-02-27
    • 2017-04-01
    相关资源
    最近更新 更多