perl如何在段落样式中获取特定的字符串

时间:2013-12-15 11:34:53

标签: perl hash multidimensional-array

我是perl的新手,还在做一些案例。我在使用perl解析日志时遇到了一些情况。

有一个数据记录:

Physical interface: ge-1/0/2, Unit: 101, Vlan-id: 101, Address: 10.187.132.3/27
  Index: 353, SNMP ifIndex: 577, VRRP-Traps: enabled
  Interface state: up, Group: 1, State: backup, VRRP Mode: Active
  Priority: 190, Advertisement interval: 1, Authentication type: none
  Advertisement threshold: 3, Delay threshold: 100, Computed send rate: 0
  Preempt: yes, Accept-data mode: yes, VIP count: 1, VIP: 10.187.132.1       
  Dead timer: 2.715s, Master priority: 200, Master router: 10.187.132.2 
  Virtual router uptime: 5w5d 12:54
  Tracking: disabled 

Physical interface: ge-1/0/2, Unit: 102, Vlan-id: 102, Address: 10.187.132.35/27
  Index: 354, SNMP ifIndex: 580, VRRP-Traps: enabled
  Interface state: up, Group: 2, State: master, VRRP Mode: Active
  Priority: 200, Advertisement interval: 1, Authentication type: none
  Advertisement threshold: 3, Delay threshold: 100, Computed send rate: 0
  Preempt: yes, Accept-data mode: yes, VIP count: 1, VIP: 10.187.132.33      
  Advertisement Timer: 0.816s, Master router: 10.187.132.35
  Virtual router uptime: 5w5d 12:54, Master router uptime: 5w5d 12:54
  Virtual Mac: 00:00:5e:00:01:02 
  Tracking: disabled 

Physical interface: ge-1/0/2, Unit: 103, Vlan-id: 103, Address: 10.187.132.67/27
  Index: 355, SNMP ifIndex: 581, VRRP-Traps: enabled
  Interface state: up, Group: 3, State: backup, VRRP Mode: Active
  Priority: 190, Advertisement interval: 1, Authentication type: none
  Advertisement threshold: 3, Delay threshold: 100, Computed send rate: 0
  Preempt: yes, Accept-data mode: yes, VIP count: 1, VIP: 10.187.132.65      
  Dead timer: 2.624s, Master priority: 200, Master router: 10.187.132.66 
  Virtual router uptime: 5w5d 12:54
  Tracking: disabled

我很好奇我们如何检索一些值并将其存储到数组中。我试过grep它,但我迷惑了如何获取特定价值。

哈希数组的预期值:

$VAR1 = {
          'interface' => 'ge-1/0/2.101',
          'address' => '10.187.132.3/27',
          'State' => 'backup'
          'Master-router' => '10.187.132.2'
        };
$VAR2 = {
          'interface' => 'ge-1/0/2.102',
          'address' => '10.187.132.35/27',
          'State' => 'master'
          'Master-router' => '10.187.132.35'
        };
$VAR3 = {
          'interface' => 'ge-1/0/2.103',
          'address' => '10.187.132.67/27',
          'State' => 'backup'
          'Master-router' => '10.187.132.66'
        };

3 个答案:

答案 0 :(得分:0)

您可以使用正则表达式来拆分每个段落。这样的事情可能有用:

/((\w|\s|-)+):\s([^,]+)/m

匹配组看起来像是:

Match 1
1.  Physical interface
2.  e
3.  ge-1/0/2
Match 2
1.  Unit
2.  t
3.  101
Match 3
1.  Vlan-id
2.  d
3.  101

如您所见, 1。对应一个键,而 3。是对应的值。您可以按照自己喜欢的方式存储这组对。

为了使其工作,日志中的每个属性都需要以逗号分隔,您列出的示例不是。假设您列出的示例是正确的,您必须稍微调整正则表达式才能使其正常工作。您可以在rubular在线测试,直到它可以正常运行。如果是逗号分隔,您可能只想将每个段落拆分为“,”,然后将每个结果拆分为“:”。

修改

在我看来,每条线都是逗号分隔的,所以如果你一次在一行上使用它们,上面提到的方法可能会很好地工作。

答案 1 :(得分:0)

解析数据:

  1. 通过将行读入一个部分从文件中获取一个部分,而行以空格开头。
  2. 拆分项目分隔符(逗号或换行符)
  3. 的部分
  4. 将第一个冒号处的每个项目拆分为键和值
  5. 对密钥进行大小写折叠并将对存储到哈希
  6. 实施草图:

    my @hashes;
    while (<>) {
      push @hashes, {} if /\A\S/;
      for my $item (split /,/) {
        my ($k, $v) = split /:/, $item, 2;
        $hashes[-1]{fc $k} = $v;
      }
    }
    

    然后,您可以从您感兴趣的哈希中提取这些信息。

答案 2 :(得分:0)

由于每条记录都是,因此您可以让Perl按local $/ = '';段落模式)读取这些块中的文件。然后,使用正则表达式捕获该段落中您想要的每个值,将该值与散列键配对,然后push将该散列引用到数组上以形成散列数组(AoH):< / p>

use strict;
use warnings;
use Data::Dumper;

my @arr;
local $/ = '';

while (<DATA>) {
    my %hash;
    ( $hash{'interface'} )     = /interface:\s+([^,]+)/;
    ( $hash{'address'} )       = /Address:\s+(\S+)/;
    ( $hash{'State'} )         = /State:\s+([^,]+)/;
    ( $hash{'Master-router'} ) = /Master router:\s+(\S+)/;

    push @arr, \%hash;
}

print Dumper \@arr;

__DATA__
Physical interface: ge-1/0/2, Unit: 101, Vlan-id: 101, Address: 10.187.132.3/27
  Index: 353, SNMP ifIndex: 577, VRRP-Traps: enabled
  Interface state: up, Group: 1, State: backup, VRRP Mode: Active
  Priority: 190, Advertisement interval: 1, Authentication type: none
  Advertisement threshold: 3, Delay threshold: 100, Computed send rate: 0
  Preempt: yes, Accept-data mode: yes, VIP count: 1, VIP: 10.187.132.1       
  Dead timer: 2.715s, Master priority: 200, Master router: 10.187.132.2
  Virtual router uptime: 5w5d 12:54
  Tracking: disabled 

Physical interface: ge-1/0/2, Unit: 102, Vlan-id: 102, Address: 10.187.132.35/27
  Index: 354, SNMP ifIndex: 580, VRRP-Traps: enabled
  Interface state: up, Group: 2, State: master, VRRP Mode: Active
  Priority: 200, Advertisement interval: 1, Authentication type: none
  Advertisement threshold: 3, Delay threshold: 100, Computed send rate: 0
  Preempt: yes, Accept-data mode: yes, VIP count: 1, VIP: 10.187.132.33      
  Advertisement Timer: 0.816s, Master router: 10.187.132.35
  Virtual router uptime: 5w5d 12:54, Master router uptime: 5w5d 12:54
  Virtual Mac: 00:00:5e:00:01:02 
  Tracking: disabled 

Physical interface: ge-1/0/2, Unit: 103, Vlan-id: 103, Address: 10.187.132.67/27
  Index: 355, SNMP ifIndex: 581, VRRP-Traps: enabled
  Interface state: up, Group: 3, State: backup, VRRP Mode: Active
  Priority: 190, Advertisement interval: 1, Authentication type: none
  Advertisement threshold: 3, Delay threshold: 100, Computed send rate: 0
  Preempt: yes, Accept-data mode: yes, VIP count: 1, VIP: 10.187.132.65      
  Dead timer: 2.624s, Master priority: 200, Master router: 10.187.132.66
  Virtual router uptime: 5w5d 12:54
  Tracking: disabled

输出:

$VAR1 = [
          {
            'Master-router' => '10.187.132.2',
            'interface' => 'ge-1/0/2',
            'address' => '10.187.132.3/27',
            'State' => 'backup'
          },
          {
            'Master-router' => '10.187.132.35',
            'interface' => 'ge-1/0/2',
            'address' => '10.187.132.35/27',
            'State' => 'master'
          },
          {
            'Master-router' => '10.187.132.66',
            'interface' => 'ge-1/0/2',
            'address' => '10.187.132.67/27',
            'State' => 'backup'
          }
        ];

希望这有帮助!