使用Perl遍历行以将匹配项拉入变量

plicqrtu  于 2022-11-15  发布在  Perl
关注(0)|答案(1)|浏览(148)

我有一个ssh捕获的输出,如下所示...

Id Name  LoopA Pos.A LoopB Pos.B Drives Temp  RevA RevB Model FormFactor
 0 cage0 0:1:1     0 1:1:1     0     16 20-27 409b 409b DCN2  SFF
 1 cage1 0:1:2     0 1:1:2     0     16 26-30 409b 409b DCS8  SFF
 2 cage2 2:1:1     0 3:1:1     0     16 22-26 409b 409b DCN2  SFF
 3 cage3 2:1:2     0 3:1:2     0     16 26-30 409b 409b DCS8  SFF

-----------Cage detail info for cage0 ---------

Position: ---
OverallState: Normal

Interface Board Info     Card0            Card1
Firmware_status          Current          Current
Product_Rev              409b             409b
State(self,partner)      OK,OK            OK,OK
VendorId,ProductId       XYRATEX,DCN2     XYRATEX,DCN2
Master_CPU               Yes              No
SAS_Addr                 5001438030F5953E 5001438030F5953E
Link_Speed(DP1,Internal) Unknown,12.0Gbps Unknown,Unknown
Locate                   Off              Off

 PS PSState ACState DCState Fan State Fan0_Speed Fan1_Speed Locate
ps0      OK      OK      OK        OK     Medium        Low    Off
ps1      OK      OK      OK        OK     Medium        Low    Off

-------------Drive Info-------------- --PortA-- --PortB--
Drive       DeviceName State  Temp(C) LoopState LoopState
0:0   5002538A59401DE1 Normal      26 OK        OK
1:0   5002538A59400DA1 Normal      27 OK        OK
2:0   5002538A59400BB1 Normal      26 OK        OK
3:0   5002538A59401571 Normal      24 OK        OK
4:0   5002538A59400C11 Normal      20 OK        OK
5:0   5002538A59402291 Normal      23 OK        OK
6:0   5002538A594014F1 Normal      24 OK        OK
7:0   5002538A49603B41 Normal      23 OK        OK
8:0   5002538B0159C4A1 Normal      25 OK        OK
9:0   5002538B0159B8D1 Normal      25 OK        OKa
10:0  5002538B0159B9E1 Normal      25 OK        OK
11:0  5002538B0159B821 Normal      26 OK        OK
12:0  5002538BC1709721 Normal      27 OK        OK
13:0  5002538BC1709521 Normal      27 OK        OK
14:0  5002538BC170A291 Normal      27 OK        OK
15:0  5002538BC170A2C1 Normal      27 OK        OK

-----------Cage detail info for cage1 ---------

Position: ---
OverallState: Normal

Interface Board Info Card0            Card1
Firmware_status      Current          Current
Product_Rev          409b             409b
State(self,partner)  OK,OK            OK,OK
VendorId,ProductId   XYRATEX,DCS8     XYRATEX,DCS8
Master_CPU           Yes              No
SAS_Addr             50050CC112A33C3E 50050CC112A3463E
Link_Speed(DP1,DP2)  12.0Gbps,Unknown Unknown,Unknown
Locate               Off              Off

 PS PSState ACState DCState Fan State Fan0_Speed Fan1_Speed Locate
ps0      OK      OK      OK        OK        Low        Low    Off
ps1      OK      OK      OK        OK        Low        Low    Off

-------------Drive Info-------------- --PortA-- --PortB--
Drive       DeviceName State  Temp(C) LoopState LoopState
0:0   5002538A594013C1 Normal      28 OK        OK
1:0   5002538A59400D71 Normal      30 OK        OK
2:0   5002538A594014A1 Normal      30 OK        OK
3:0   5002538A59400C01 Normal      29 OK        OK
4:0   5002538A59402651 Normal      29 OK        OK
5:0   5002538A594015C1 Normal      29 OK        OK
6:0   5002538A59400C21 Normal      26 OK        OK
7:0   5002538A59402131 Normal      26 OK        OK
8:0   5002538B0159B8F1 Normal      28 OK        OK
9:0   5002538B0159B891 Normal      27 OK        OK
10:0  5002538B0159BE21 Normal      27 OK        OK
11:0  5002538B0159BD01 Normal      28 OK        OK
12:0  5002538BC1709791 Normal      29 OK        OK
13:0  5002538BC17096B1 Normal      29 OK        OK
14:0  5002538BC17096A1 Normal      29 OK        OK
15:0  5002538BC1709861 Normal      29 OK        OK

-----------Cage detail info for cage2 ---------

Position: ---
OverallState: Normal

Interface Board Info     Card0            Card1
Firmware_status          Current          Current
Product_Rev              409b             409b
State(self,partner)      OK,OK            OK,OK
VendorId,ProductId       XYRATEX,DCN2     XYRATEX,DCN2
Master_CPU               No               Yes
SAS_Addr                 5001438030F5953E 5001438030F5953E
Link_Speed(DP1,Internal) Unknown,12.0Gbps Unknown,12.0Gbps
Locate                   Off              Off

 PS PSState ACState DCState Fan State Fan0_Speed Fan1_Speed Locate
ps0      OK      OK      OK        OK     Medium     Medium    Off
ps1      OK      OK      OK        OK     Medium     Medium    Off

-------------Drive Info-------------- --PortA-- --PortB--
Drive       DeviceName State  Temp(C) LoopState LoopState
0:0   5002538A59402641 Normal      24 OK        OK
1:0   5002538A594014C1 Normal      24 OK        OK
2:0   5002538A594013A1 Normal      25 OK        OK
3:0   5002538A594013B1 Normal      23 OK        OK
4:0   5002538A594026E1 Normal      24 OK        OK
5:0   5002538A594013E1 Normal      23 OK        OK
6:0   5002538A59402341 Normal      23 OK        OK
7:0   5002538A59401391 Normal      22 OK        OK
8:0   5002538B0159B981 Normal      25 OK        OK
9:0   5002538B0159BE51 Normal      25 OK        OK
10:0  5002538B0159B7E1 Normal      25 OK        OK
11:0  5002538B0159BE41 Normal      25 OK        OK
12:0  5002538BC17097F1 Normal      26 OK        OK
13:0  5002538BC1709671 Normal      26 OK        OK
14:0  5002538BC17095E1 Normal      26 OK        OK
15:0  5002538BC1709811 Normal      26 OK        OK

-----------Cage detail info for cage3 ---------

Position: ---
OverallState: Normal

Interface Board Info Card0            Card1
Firmware_status      Current          Current
Product_Rev          409b             409b
State(self,partner)  OK,OK            OK,OK
VendorId,ProductId   XYRATEX,DCS8     XYRATEX,DCS8
Master_CPU           No               Yes
SAS_Addr             50050CC11343BA3E 50050CC11343BC3E
Link_Speed(DP1,DP2)  12.0Gbps,Unknown Unknown,Unknown
Locate               Off              Off

 PS PSState ACState DCState Fan State Fan0_Speed Fan1_Speed Locate
ps0      OK      OK      OK        OK        Low        Low    Off
ps1      OK      OK      OK        OK        Low        Low    Off

-------------Drive Info-------------- --PortA-- --PortB--
Drive       DeviceName State  Temp(C) LoopState LoopState
0:0   5002538A59401531 Normal      28 OK        OK
1:0   5002538A59402731 Normal      30 OK        OK
2:0   5002538A59400BA1 Normal      29 OK        OK
3:0   5002538A4960C0A1 Normal      29 OK        OK
4:0   5002538A59400DB1 Normal      28 OK        OK
5:0   5002538A594026D1 Normal      29 OK        OK
6:0   5002538A59401561 Normal      27 OK        OK
7:0   5002538A59400D61 Normal      26 OK        OK
8:0   5002538B0159C491 Normal      28 OK        OK
9:0   5002538B0159BE31 Normal      27 OK        OK
10:0  5002538B0159C4F1 Normal      27 OK        OK
11:0  5002538B0159B1D1 Normal      27 OK        OK
12:0  5002538BC1709711 Normal      27 OK        OK
13:0  5002538BC1709731 Normal      29 OK        OK
14:0  5002538BC1709651 Normal      29 OK        OK
15:0  5002538BC1709821 Normal      27 OK        OK

我使用了一个循环来尝试并拉出机箱状态和电源状态、交流、直流和风扇状态
我需要如下输出;但我认为我需要另一个循环来处理第二个电源:

[Cage: cage0 - [Overall Status: Normal, [Power Supply ps0 State: OK, AC: OK, DC: OK, Fan: OK],[Power Supply ps1 State: OK, AC: OK, DC: OK, Fan: OK]], Cage: cage1 - [Overall Status: Normal, [Power Supply ps0 State: OK, AC: OK, DC: OK, Fan: OK],[Power Supply ps1 State: OK, AC: OK, DC: OK, Fan: OK]], Cage: cage2 - [Overall Status: Normal, [Power Supply ps0 State: OK, AC: OK, DC: OK, Fan: OK],[Power Supply ps1 State: OK, AC: OK, DC: OK, Fan: OK]], Cage: cage3 - [Overall Status: Normal, [Power Supply ps0 State: OK, AC: OK, DC: OK, Fan: OK],[Power Supply ps1 State: OK, AC: OK, DC: OK, Fan: OK]]]

我的代码如下所示:

my $status = 0;
my @cages;
my $cage_name = "";
my $overall_status= "";
my $ps= "";
my $ps_state= "";
my $ps_ac= "";
my $ps_dc= "";
my $ps_fan= "";
my $section = 0;
my $section_status = 0;
my $cnt = 0;

my $ssh = Net::OpenSSH->new($hostname, user => $username, password => $password, master_opts => [-o => "StrictHostKeyChecking=no"]);
$ssh->error and die "Couldn't establish SSH connection: ". $ssh->error;

my ($out, $err) = $ssh->capture2("showcage -d");
if ( $err ) {
    print "UNKNOWN - Cannot establish connection ($err)\n";
    exit 3;
}

my @output = split "\n", $out;

#Get all cage names and overal status
foreach my $line ( @output ) {
    
    if ( $line =~ m/^\-+Cage\sdetail\sinfo\sfor\s(\w+).*$/)  {          
        
        $cage_name = $1;
        $section++;
    }
    
    elsif ( $line =~ m/^OverallState:\s(\w+).*$/)  {
        
        $overall_status = $1;
        
        if ($overall_status ne "NORMAL") {
            $status = 2;
        }
        
        $section_status++;
    }
    
    
    elsif ( $line =~ m/^(ps\d)\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+).*$/) {
        
        $ps = $1;
        $ps_state = $2;
        $ps_ac = $3;
        $ps_dc = $4;
        $ps_fan = $5;
        
        
        if ( $ps_state ne "OK" or $ps_ac ne "OK" or $ps_dc ne "OK" or $ps_fan ne "OK" ){
            $status = 2;
        }
        
        $cnt++;
        
        
    }
    
    if ($section > 0 and $section_status > 0 and $cnt >= 1) {
            $np->add_message(
            $status,
            "[Cage: $cage_name - [Overall Status: $overall_status, [Power Supply: $ps - State: $ps_state, AC: $ps_ac, DC: $ps_dc, Fan: $ps_fan]]]"
         );
         
        $section = 0;
        $section_status = 0;
    
    }
    
}
i2loujxw

i2loujxw1#

如果您先将输入解析为Perl数据结构,然后以您需要的格式打印出来,维护起来会更简单。这将从标准输入读取数据。我将让您在网络获取中打补丁:

use strict;
use Data::Dumper;

sub parse {
  my ($cage, $state);
  my @headers;
  my %report;
  while (<>) {
    if (/Cage detail info for (\w+)/) {
      $cage = $1;
    } elsif (/^ PS/) {
      s/Fan State/Fan_State/; # Work around broken header.
      @headers = split;
    } elsif (/OverallState: (\w+)/) {
      $state = $1;
    } elsif (/^(ps\d+)\s/) {
      my @values = split;
      my %ps_row;
      @ps_row{@headers} = @values;
      $report{$cage}->{$ps_row{PS}} = \%ps_row;
      $report{$cage}->{State} = $state;
    }
  }
  \%report
}

sub format_report {
  my $report = shift;
  my $s = '[';
  my $sep = '';
  foreach my $cage (sort keys(%$report)) {
    my $cage_data = $report->{$cage};
    $s .= $sep;
    $s .= "Cage: $cage - [Overall Status: $cage_data->{State}";
    foreach my $ps (sort keys (%$cage_data)) {
      next unless $ps =~ /^ps/;
      $s .= ", [Power Supply $ps";
      my $ps_row = $cage_data->{$ps};
      $s .= " State: $ps_row->{PSState}";
      $s .= ", AC: $ps_row->{ACState}";
      $s .= ", DC: $ps_row->{DCState}";
      $s .= ", Fan: $ps_row->{Fan_State}";
      $s .= ']';
    }
    $s .= ']';
    $sep = ', ';
  }
  $s .= ']';
}

sub main {
  my $report = parse;
  print Dumper($report);
  my $formatted_report = format_report($report);
  print "$formatted_report\n";
}

main;

警告:我的perl是生 rust 的。但是输出与你的匹配。

相关问题