如何加入嵌套的Perl哈希?

时间:2014-10-07 13:24:23

标签: perl csv hash

我有一个Perl哈希,我存储有关LUN的信息。它具有以下结构:

my %luns = (
    360000 => {
        Devices => [
            {   Major_Minor  => "8:144",
                SCSI_Address => "1:0:0:8",
                SCSI_Device  => "sdj",
                SCSI_Host    => "host1",
            },
            {   Major_Minor  => "129:48",
                SCSI_Address => "3:0:0:8",
                SCSI_Device  => "sder",
                SCSI_Host    => "host3",
            },
        ],
        DM_Device => "dm-13",
        Size      => "45G",
        WWID      => 360000,
    },
    360001 => {
        Devices => [
            {   Major_Minor  => "70:144",
                SCSI_Address => "1:0:1:39",
                SCSI_Device  => "sddb",
                SCSI_Host    => "host1",
            },
            {   Major_Minor  => "135:48",
                SCSI_Address => "3:0:1:39",
                SCSI_Device  => "sdij",
                SCSI_Host    => "host3",
            },
        ],
        DM_Device => "dm-53",
        Size      => "200G",
        WWID      => 360000,
    },
);

如何使用join获取所有SCSI_Devices的逗号分隔列表,例如360000

2 个答案:

答案 0 :(得分:1)

你正在使用Hash of Hash of Hash of Hash。要了解如何使用此类结构,建议您阅读perldsc - Perl Data Structures Cookbook

在这种情况下,以下循环将打印出您的每个设备列表:

for my $id ( sort { $a <=> $b } keys %luns ) {
    my @devices = map { $_->{SCSI_Device} } @{ $luns{$id}{Devices} };
    print "$id - @devices\n";
}

输出:

360000 - sdj sder
360001 - sddb sdij

Live Demo

答案 1 :(得分:0)

你说你想要一个LUN 360000的值列表,所以首先需要

$luns->{36000}

是具有Devices元素的另一个哈希,其中数组引用为值,DM_DeviceSize和{{1}元素,其值是简单的标量。

所以大概你想要的是

列表
WWID

是一个对哈希的引用数组,每个都有$luns->{36000}{Devices} Major_MinorSCSI_AddressSCSI_Device个元素。< / p>

听起来你想要SCSI_Host元素,SCSI_Device是帮助你解决这个问题的理想工具

map

最后一步是一个很大的飞跃,它可能有助于在你的代码中分离它。例如,您可以将引用复制到my @scsi_devices = map { $_->{SCSI_Device} } @{ $luns->{360000}{Devices} }; 的设备列表,如此

360000

并使用

从该数组中的每个哈希中提取my $devices = $luns->{360000}{Devices};
SCSI_Device

无论哪种方式,数组引用必须 dereferenced ,并且必须提取该数组中每个哈希的必需元素。

要获取CSV记录,除非数据可能包含双引号逗号,您只需要my @scsi_devices = map { $_->{SCSI_Device} } @$devices; join的结果

map

<强>输出

print join(',', @scsi_devices), "\n";

虽然我认为这不符合你的实际需要。如果这不清楚,请询问。