【问题标题】:perl how to grab spesific string in paragraph styleperl如何以段落样式获取特定字符串
【发布时间】:2014-01-02 20:18:25
【问题描述】:

我是 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'
        };

【问题讨论】:

  • 发布你拥有的东西,即使它不起作用。这样,我们就会知道你已经尝试了一些东西
  • 也许您还应该准确地描述您希望从该日志中得到什么,除非您希望人们猜测。

标签: perl hash multidimensional-array


【解决方案1】:

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

/((\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 在线测试它,直到它工作。如果它是逗号分隔的,你可能只想用“,”分割每个段落,然后在“:”上分割每个结果。

编辑:

在我看来,每一行都是逗号分隔的,因此如果您一次在一行上使用上述方法,它们可能会非常有效。

【讨论】:

  • 不需要捕获第 2 组。您可以使用(?:\w|\s|-) 或简单地使用[\w\s-] 而不是(\w|\s|-)
【解决方案2】:

解析数据:

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

一个实现的草图:

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

然后你可以从你感兴趣的哈希中提取那些信息。

【讨论】:

  • 您应该在拆分中使用 2 的限制。
【解决方案3】:

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

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'
          }
        ];

希望这会有所帮助!

【讨论】:

  • 对于 "State:" ,不知何故它没有获取值.. $VAR1 = { 'Master-router' => undef, 'interface' => 'ge-1/0/2 ', '地址' => '10.187.132.3/27', '状态' => undef };
  • @warkomers - 它确实捕获了您显示的三个数据块中的所需字段。捕获在哪个数据块中失败?也许有一个带有不同标签的块。如果您愿意,请将该数据块附加到您的原始数据集中,并在您完成此操作后通知我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-20
  • 1970-01-01
  • 2018-01-24
  • 1970-01-01
  • 2017-07-28
相关资源
最近更新 更多