我想将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;
}
但它不起作用。 :(好吗?
答案 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";
}