将systool输出解析为perl

时间:2017-04-28 14:04:06

标签: perl

我想将systool的输出解析为perl哈希值,以csv格式打印每个找到的具有ist属性和值的设备。

# systool  -c fc_host -v
Class = "fc_host"

  Class Device = "host11"
    dev_loss_tmo        = "30"
    fabric_name         = "0x1000c4f57c548ba0"
    issue_lip           = <store method only>
    max_npiv_vports     = "255"
    maxframe_size       = "2048 bytes"
    node_name           = "0x20000090faf02a08"
    npiv_vports_inuse   = "0"
    port_id             = "0xcf0500"
    port_name           = "0x10000090faf02a08"
    port_state          = "Online"    supported_classes   = "Class 3"

  Class Device = "host12"
    dev_loss_tmo        = "30"
    fabric_name         = "0x1000c4f57c54a0d0"
    ....

我只是不知道如何开始将这个结构化数据转换为哈希值,甚至是哈希列表(每个找到的HBA的一个哈希值)。 我正在尝试这样的事情:

open (SysTool, "/usr/bin/systool -c fc_host -v |") or die "problem running systool";
while (<SysTool>) {
  %FChost  = $1 if /Class Device =:\s+"(\w+)"$/;
  ($attribute, $value) = split /=/, $_;
   $FChost{$attribute} = $value;
}

但它不起作用。 :(好吗?

1 个答案:

答案 0 :(得分:0)

您的代码无效的原因是这一行:

%FChost  = $1 if /Class Device =:\s+"(\w+)"$/;

你打算做什么?我的意思是,对于初学者来说 - 根据你的输入(在那里没有:,它永远不会匹配)但是甚至纠正你将一个标量分配给一个哈希,那就是给你:

$VAR1 = {
          'host11' => undef
        };

它除了排序之外,但是每次循环迭代都会破坏其他所有记录,否则你似乎没有做任何事情。

另外 - 请use strict; use warnings; - 它有很大帮助。

这里有用的事情是 - 将$/设置为' ',它将以段落模式运行。

所以:

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;

local $/ = ''; 

while ( <> ) {
   my %record = m/(\w+)\s*=\s*\"(\S+)\"/g;
   print Dumper \%record;
}

这会给你一个如下记录:

$VAR1 = {
          'node_name' => '0x20000090faf02a08',
          'port_state' => 'Online',
          'port_id' => '0xcf0500',
          'max_npiv_vports' => '255',
          'dev_loss_tmo' => '30',
          'Device' => 'host11',
          'port_name' => '0x10000090faf02a08',
          'npiv_vports_inuse' => '0',
          'fabric_name' => '0x1000c4f57c548ba0'
        };

如果您愿意,可以将push放入记录数组中,或使用哈希切片进行打印:

my @fields = qw(port_id port_name port_state);
print join ",", @record{@fields},"\n";

注意 - 你应该也可以使用词法文件句柄和3 arg open:

open ( my $systool, '-|', '/usr/bin/systool -c fc_host -v' ); 

这样的事情:

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;

open ( my $systool, '-|', '/usr/bin/systool -c fc_host -v' ); 
local $/ = '';

my @records; 

while ( <$systool> ) {
    next unless m/Device/;
    push @records, {m/(\w+)\s*=\s*\"(\S+)\"/g};
}

#print for debug
print Dumper \@records;

my @headers = qw ( Device port_id port_name port_state );
foreach my $record ( @records ) {
   print join ",", @{$record}{@headers},"\n";
}