简体   繁体   中英

Regex string extraction in Perl Script

my text from a cmd output is like this:

  pool: pool0
 state: ONLINE
status: Some supported features are not enabled on the pool. The pool can
        still be used, but some features are unavailable.
action: Enable all features using 'zpool upgrade'. Once this is done,
        the pool may no longer be accessible by software that does not support
        the features. See zpool-features(5) for details.
  scan: scrub repaired 0B in 01:24:15 with 0 errors on Sun Nov 14 01:48:17 2021
config:

        NAME        STATE     READ WRITE CKSUM
        pool0       ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            sdc     ONLINE       0     0     0
            sdd     ONLINE       0     0     0

errors: No known data errors

I would like to extract the values for pool, state, status, action, scan, config and errors. I tryíed to use a regex gen/test side like https://regexr.com/ or https://regex101.com/ . There i get my matches and the value in the "name" group for the pool example but in shell i can see nothing

use IO::Socket::INET;
my $strCmdErg = `/sbin/zpool status`;

my $poolname=  $strCmdErg=~ /pool:\s(.*$)/gm;
print "PoolName: $poolname \n";

my $state = $strCmdErg=~ /\sstate:\s(.*$)\n/gm;
print "Status: $state \n";

output

PoolName: 1
Status: 1

I think the "one" is an indicator for a match.

Thank you!

my $poolname=

Is doing the regex in scalar context, which is why you get 1, the number of matches, returned. You need to change it to list context like

 my ($poolname) =

in order for the captured text to be assigned to the variable.

Perl captures use the variables $1 , $2 , etc:

$strCmdErg =~ /pool:\s(.*$)/m;
my $poolname = $1;
print "PoolName: $poolname \n";

You are correct that your 1 values in the code you posted are the return value of the match, which is 1 for true .

See https://www.perltutorial.org/regular-expression-extracting-matches/ for more information.

This kind of human readable output can be parsed into a hash with split fairly easily.

use strict;
use warnings;
use Data::Dumper;

my $data = do { local $/; <DATA> };    # slurp text into variable
my %data = grep $_,                         # remove empty fields
           map { chomp; $_ }                # remove trailing newline
           split /^\s*(\w+): */m, $data;    # split the data
print Dumper \%data;

__DATA__
  pool: pool0
 state: ONLINE
status: Some supported features are not enabled on the pool. The pool can
        still be used, but some features are unavailable.
action: Enable all features using 'zpool upgrade'. Once this is done,
        the pool may no longer be accessible by software that does not support
        the features. See zpool-features(5) for details.
  scan: scrub repaired 0B in 01:24:15 with 0 errors on Sun Nov 14 01:48:17 2021
config:

        NAME        STATE     READ WRITE CKSUM
        pool0       ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            sdc     ONLINE       0     0     0
            sdd     ONLINE       0     0     0

errors: No known data errors

Output:

$VAR1 = {
          'config' => '

        NAME        STATE     READ WRITE CKSUM
        pool0       ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            sdc     ONLINE       0     0     0
            sdd     ONLINE       0     0     0',
          'status' => 'Some supported features are not enabled on the pool. The pool can
        still be used, but some features are unavailable.',
          'state' => 'ONLINE',
          'action' => 'Enable all features using \'zpool upgrade\'. Once this is done,
        the pool may no longer be accessible by software that does not support
        the features. See zpool-features(5) for details.',
          'errors' => 'No known data errors',
          'pool' => 'pool0',
          'scan' => 'scrub repaired 0B in 01:24:15 with 0 errors on Sun Nov 14 01:48:17 2021'
        };

Now you can easily print a field by supplying the field name as a hash key. For example:

print "PoolName: $data{pool}\n";
print "State: $data{state}\n";

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM