perl 散列表:有效地计数与关键字匹配散列

e5nszbig  于 2022-11-15  发布在  Perl
关注(0)|答案(1)|浏览(146)

我想检查ip -j在perl中添加show eno 1的json输出。我想计算NIC有多少个ipv4地址。我仍然需要ipv6信息,所以我想避免运行两次带有-4和-6标志的/usr/bin/ip命令。
现在我可以访问ip信息,如下所示:$nic->{addr_info}[0]->{local}对于每个条目,$nic->{addr_info}[$ip_info_index]->{family}将给予IP类型(inet或inet 6)
在大多数情况下,我的表中有2个条目:一个用于v4,一个用于v6,但有时我有2个v4条目a,并希望在我的软件中发出警告“不支持”。
$nic->{addr_info}[$ip_info_index]->{family}将给予条目的类型。
是否有一些优雅的技巧使用Map和标量来计算有多少个$nic->{addr_info}[$ip_info_index]->{family}等于“inet”(而不是“inet 6”)
(我可以在$ip_info_index上循环,并在每次看到'inet'时增加一个计数器,但这似乎并不优雅)。

DB<3> p Dumper($nic)
$VAR1 = {
          'txqlen' => 1000,
          'address' => '00:26:b9:7d:c0:ee',
          'broadcast' => 'ff:ff:ff:ff:ff:ff',
          'link_type' => 'ether',
          'group' => 'default',
          'mtu' => 1500,
          'qdisc' => 'mq',
          'flags' => [
                       'BROADCAST',
                       'MULTICAST',
                       'UP',
                       'LOWER_UP'
                     ],
          'operstate' => 'UP',
          'ifindex' => 2,
          'addr_info' => [
                           {
                             'valid_life_time' => 30949,
                             'preferred_life_time' => 30949,
                             'label' => 'eno1',
                             'family' => 'inet',
                             'scope' => 'global',
                             'noprefixroute' => bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' ),
                             'prefixlen' => 24,
                             'local' => '172.16.59.72',
                             'broadcast' => '172.16.59.255',
                             'dynamic' => $VAR1->{'addr_info'}[0]{'noprefixroute'}
                           },
                           {
                             'family' => 'inet6',
                             'local' => 'fe80::226:b9ff:fe7d:c0ee',
                             'valid_life_time' => 4294967295,
                             'preferred_life_time' => 4294967295,
                             'prefixlen' => 64,
                             'scope' => 'link'
                           }
                         ],
          'ifname' => 'eno1'
        };

对于addr_info表,我想计算有多少个hash具有'family' =〉'inet'(对于'inet 6'也是一样)。如果设置了多个ipv4或ipv6,我需要失败。如果您想在linux系统上测试,$nic是这样获得的:

my $ip_addr_output = `LC_ALL=C /sbin/ip -j addr 2>/dev/null`;
uxh89sit

uxh89sit1#

我想这就是你想要的。
$nic->{addr_info}是对数组的引用,其中每个元素描述连接到接口的一个IP地址。
因此@{ $nic->{addr_info} }取消引用该数组,这样您就可以将其传递给需要数组或列表的函数。grep就是一个这样的函数,它过滤列表,只返回列表中满足某些条件的元素。因此,我们可以使用以下函数获得IPv4地址列表:

grep { $_->{family} eq 'inet' } @{ $nic->{addr_info} }

如果你在标量上下文中调用'grep,它不会给予列表,而是给出列表中的项数。

scalar grep { $_->{family} eq 'inet' } @{ $nic->{addr_info} }

因此,您可以使用以下代码:

say "$nic->{ifname} : ", scalar grep { $_->{family} eq 'inet' } @{ $nic->{addr_info} };

相关问题