Paul Lalli wrote:
On Jul 18, 6:43 am, [EMAIL PROTECTED] (kapil.V) wrote:
    su-2.05b# df -h .
        Filesystem Size Used Avail Capacity Mounted on
        /dev/ad0s1e 136G 102G 23G 82% /home

    From my script I do:
         my $du = qx#df -h \.#;
         ($total,$used) = $du =~ /([0-9]+(\.[ 0-9]+)?)[ M|G]/sg;
         print "Total:$total\nUsed:$used\ n";

         Output:
         Total:136G
         Used:

   Why is "$used" not set?

Because you're not understanding the return value of m//.  Which is
understandable, because there's so many things that can affect what
this operator returns.  In this case, you have three factors:
* It's being called in list context
* It's using the /g modifier
* It contains capturing parentheses.

In that case, Perl will repeatedly search the string for the pattern,
finding all instances of the entire pattern.  The return value will be
a list of ALL instances of ALL captured submatches, in order.  (ie,
the first $1, the first $2, the first $3, the second $1, the second
$2, the second $3, etc)

Take a look at this:
$ perl -lwe'
my $du = "/dev/ad0s1e 136G 102G 23G 82% /home";
print for $du =~ /([0-9]+(\.[ 0-9]+)?)[ M|G]/sg;
'
136
Use of uninitialized value in print at -e line 3.

102
Use of uninitialized value in print at -e line 3.

23
Use of uninitialized value in print at -e line 3.


Do you see the issue now?  Your pattern is successfully matched
(because of the /g modifier) a total of three times.  The first time
through, the first set of capturing parentheses matches 136.  The
second set is undefined, because you allowed it to be optional, so
that part wasn't matched at all (ie, there was no "period-and-more-
digits" following the set of digits).  So the first two return values
of the m// are 136 and undef.

Then the second time through, the first set of capturing parentheses
matched 102, and the second set again didn't match anything, so the
third and fourth return values of the m// are 102 and undef.

The real problem here is that you don't want the second set of
parentheses to be capturing.  You only want that period-and-digits to
be associated with each other so you can make them optional as a
group.  This is known as "clustering" rather than capturing.  To make
parentheses cluster without capturing, you start them with a ?:
sequence.  Observe:

$ perl -lwe'
my $du = "/dev/ad0s1e 136G 102G 23G 82% /home";
print for $du =~ /([0-9]+(?:\.[ 0-9]+)?)[ M|G]/sg;
'
136
102
23

Now, there is only one set of capturing parentheses in this pattern.
The first time through, that set of parentheses matches 136.  The
second time through, it maches 102.  The third time through, it
matches 23.  So the return value of this m// will be (136, 102, 23).

For more information, please read:
perldoc perlre
perldoc perlreref
perldoc perlretut

Hope this helps,
Paul Lalli

Thanks a lot. The issue is clear now. Previously, I was under the impression that a nested paranthesis would not qualify as a return
value for a matched pattern.

Thx.

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to