Perl:使用缩放器引用替换数组哈希中的值

时间:2018-09-25 17:17:34

标签: perl hash reference

尝试在此哈希中将空值替换为已知的可信值。我正在这样做,但是我的s /.../.../ g的b / c表示(@ ...)的打印dup值,所以自从搜索后,也许我正在处理所有这些错误。这是我的代码,请提供您的帮助。谢谢!

use strict;
use warnings;
my $hmc01 = qq(rsqxxxx.xxxx.com);
my $key   = qq(/home/root/.ssh/id_rsa_hmcscan);
# get frame names
push my @frames, qx(ssh -i $key hscroot\@$hmc01 lssyscfg -r sys -F 
name|sort);
chomp @frames;
my (%cpudata,$h,$cpus,$max);
my $cspu  = q|configurable_sys_proc_units|;
my $caspu = q|curr_avail_sys_proc_units|;
# get cpu attributes for each lpar on each frame
foreach my $f (@frames) {
    open ( my $FD, "-|", "ssh -i $key hscroot\@$hmc01 lshwres -r proc -m 
    $f --level sys -F $cspu,$caspu" ) or warn $!;
    print  "\nFrame $f has,$cspu,$caspu,";
    for my $fdln (<$FD>) {
        my $cspu2  = +(split /\,/, $fdln)[0];
        my $caspu2 = +(split /\,/, $fdln)[1];
    }
    open ( my $FDD, "-|", "ssh -i $key hscroot\@$hmc01 lshwres -r proc -m 
    $f --level lpar -F 
    \"lpar_name\\;curr_proc_units\\;curr_max_proc_units\" ") or warn $!;

    # POPULATE in format name,cpu,maxcpu
    my ($h,$ccpu,$mcpu);    
    while (( my $fddln = <$FDD> )) {
        $h    = +(split(";", $fddln, 0))[0];
        $ccpu = +(split(";", $fddln, 0))[1];
        $mcpu = +(split(";", $fddln, 0))[2];
        push @{$cpudata{$h}}, ($ccpu,$mcpu);
    }
}
# REPLACE
foreach my $lpar (sort keys %cpudata) {
    if ( grep /null/i, @{$cpudata{$lpar}} ) {
        #my $lop = $lpar;
        ($new) = qx(ssh -i $key hscroot\@$hmc01 lshwres -r proc -m RSQ-20-p8408-44E-SN783739X --level lpar --filter \"lpar_names\=$lpar\" -F \"curr_procs,curr_max_procs\");
        #s/null/$new/g for @{$cpudata{$lop}};
        @{$cpudata{$lpar}} = map { s/null/$new/r } @{$cpudata{$lpar}};
    }
    print "$lpar,", join(",",@{$cpudata{$lpar}}),"\n";
}

use Data::Dumper;   print Dumper \%cpudata;
## INCORRECT b/c of DUPED output
'wassapxxxx' => [
'6,8
',
'6,8

'
],
## CORRECT OUTPUT
'twccntxxxxx' => [
'0.2',
'2.0
'
],

# %cpudata, raw
# 'wassapxxxxx' => [
# '2.5',
# '4.0
#'
#],
# wassapxxxx' => [
# null',
# 'null
#'
#                        ],
# 'rsqgangliaxxx' => [
# '0.5',
# '2.0
#'

# output of system call top-to-bottom
# lssyscfg -r sys -F name|sort
# IDI-8202-E4B-SN10AAF0B
# RSQ-17-p8286-41A-SNxxxxx
# RSQ-18-p8286-41A-SNxxxxx
# RSQ-19-p8408-44E-SNxxxxx
# RSQ-20-p8408-44E-SNxxxxx
# RSQ-21-p9009-41A-SNxxxxx
# RSQ-22-p9009-41A-SNxxxxx
# RSQ-DR01-8202-E4C-SNxxxx
# WilData-8202-E4C-SNxxxxx

# lshwres -r proc -m RSQ-22-p9009-41A-SNxxxxx --level lpar -F 
# "lpar_name;curr_proc_units;curr_max_proc_units"
# DTMiSeriesTxx;0.1;1.0
# NWSPRDxx;0.1;1.0
# MXDPRDxx;0.2;2.0
# TWCICOPE3xxx;0.1;1.0
# vios2xx;1.0;2.0
# R2iSeriesRsxxxx;0.1;1.0
# vios2xxx;1.0;2.0
# wassapdxxx;null;null
# wassapxxxx;null;null

对于某些节点,我必须使用变量curr_procs,curr_max_procs 而不是curr_proc_units; curr_max_proc_units,因此是变量$ new。我不确定要添加什么,我认为代码非常清楚。请具体说明,我也可以!谢谢!

1 个答案:

答案 0 :(得分:0)

除了上面的注释之外,该代码难以阅读且因此难以理解,并且您的数据结构未准确描述...

您要用'null'中的值代替标量值$new,对吗?是否需要正则表达式,或者如果它是'null',足以替换该值:

if ( grep /null/i, @{$cpudata{$lpar}} ) {

    # why are your storing $lpar in $lop?
    my $lop = $lpar;

    # $new has to use unique variables for specific data #
    $new = qx(ssh -i $key hscroot\@$hmc01 lshwres -r proc -m RSQ- 
    20-p8408-44E-SNCCCCCCC --level lpar --filter \"lpar_names\=$lop\" -F 
    \"curr_procs,curr_max_procs\");

    ## maybe map will do the substitution in case you do not need
    ## a regular expression, just use 
    ##     { ($_ eq "null") ? $new : $_ }
    ## as map instruction
    @{$cpudata{$lop}} = map { s/null/$new/g } @{$cpudata{$lop}};
    }

编辑:您的编辑显示,您需要替换"null\n"。因此,您可能要删除换行符,因此使用s/null\s*/$new/g。顺便说一句...您期望进行一次替换,因此不需要/g