intoperl has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks, I want to filer some text from a linux output, and store it in variable for report purposes. Below is the text i am processing

PV /dev/sda2 VG VGExaDb lvm2 [557.62 GB / 20.50 GB free] PV /dev/sda3 VG VGExaDb lvm2 [278.88 GB / 0 free]

So, from above text, i want to extract (/dev/sda2) (/dev/sda3) and 557.62 GB / 20.50 GB free. I did write a regex code which is not working for me. Please assist. Thanks

Replies are listed 'Best First'.
Re: Text filer and assign
by karlgoethebier (Abbot) on Oct 06, 2015 at 11:38 UTC
    print join ' ', (split /\s/, $line)[1, 9, 10, 11, 12, 13, 14];

    Much simpler. Regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

      or:

      print join ' ', (split /\s/, $line)[1, 9 .. 14];

        I swear that i dreamed last night that i forgot this...

        Best regards, Karl

        «The Crux of the Biscuit is the Apostrophe»

Re: Text filer and assign
by Anonymous Monk on Oct 06, 2015 at 08:15 UTC

    I did write a regex code which is not working for me. Please assist. Thanks

    Please show the code you have written, its easier to help that way

      code snippet is below :

      #!/usr/bin/perl -w use strict; system("pvscan>>pv.txt1"); open my $FH,"pv.txt1" or die "Cannot open file: $!"; while(my $line = <$FH>){ my $pvname = $line =~ /\[\d+\.\d+\sGB\s\/\s\d+\.\d+\sGB\]/i; print $pvname; }

      i want the assignment to look like :

      pvname = [557.62 GB / 20.50 GB free]

        Most likely, you want to use "capturing" (see perlre) to keep the stuff that interests you:

        ... if( $line =~ /(\[\d+\.\d+\sGB\s\/\s\d+\.\d+\sGB\])/i ) { my $pvname = $1; print $pvname; };

        Note that your regular expression does not match the result you want, because your result has the string free in it, while your regular expression will not match that. You should add the string at the appropriate place.

        While it makes debugging easier, you don't need a temp file:

        for my $line (`pvscan`) { ... };
        I humly think you need a regex playfield: as usual i suggest two tools:


        I find also YAPE::Regex::Explain useful:
        >perl -MYAPE::Regex::Explain -e " print YAPE::Regex::Explain->new(qr/\ +[\d+\.\d+\sGB\s\/\s\d+\.\d+\sGB\]/i)->explain();" The regular expression: (?i-msx:\[\d+\.\d+\sGB\s/\s\d+\.\d+\sGB\]) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?i-msx: group, but do not capture (case-insensitive) (with ^ and $ matching normally) (with . not matching \n) (matching whitespace and # normally): ---------------------------------------------------------------------- \[ '[' ---------------------------------------------------------------------- \d+ digits (0-9) (1 or more times (matching the most amount possible)) ---------------------------------------------------------------------- \. '.' ---------------------------------------------------------------------- \d+ digits (0-9) (1 or more times (matching the most amount possible)) ---------------------------------------------------------------------- \s whitespace (\n, \r, \t, \f, and " ") ---------------------------------------------------------------------- GB 'GB' ---------------------------------------------------------------------- \s whitespace (\n, \r, \t, \f, and " ") ---------------------------------------------------------------------- / '/' ---------------------------------------------------------------------- \s whitespace (\n, \r, \t, \f, and " ") ---------------------------------------------------------------------- \d+ digits (0-9) (1 or more times (matching the most amount possible)) ---------------------------------------------------------------------- \. '.' ---------------------------------------------------------------------- \d+ digits (0-9) (1 or more times (matching the most amount possible)) ---------------------------------------------------------------------- \s whitespace (\n, \r, \t, \f, and " ") ---------------------------------------------------------------------- GB 'GB' ---------------------------------------------------------------------- \] ']' ---------------------------------------------------------------------- ) end of grouping ----------------------------------------------------------------------


        HtH
        L*
        There are no rules, there are no thumbs..
        Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
        system("pvscan>>pv.txt1"); open my $FH,"pv.txt1" or die "Cannot open file: $!";

        I see that you append to the pv.txt1 file which means more lines to parse every time you run the script; is this actually intended? Unless you want to keep the output of pvscan hanging around you can open a file handle directly on piped commands. Something like:-

        open my $pvscanFH, '-|', 'pvscan' or die "Cannot fork pvscan: $!\n";

        You can then read the command output line by line just as if it was a file on disk.

        I hope this is helpful.

        Cheers,

        JohnGG