You can always choose to walk the kings road:
<snip>
use Filesys::DiskSpace;

($fs_type, $fs_desc, $used, $avail, $fused, $favail) = df $dir;
$total = $used + $avail;
print "Total:$total\nUsed:$used\ n";
</snip>

Yaron Kahanovitch


----- Original Message -----
From: "kapil.V" <[EMAIL PROTECTED]>
To: beginners@perl.org, "Paul Lalli" <[EMAIL PROTECTED]>
Cc: beginners@perl.org
Sent: 10:55:01 (GMT+0200) Africa/Harare יום שישי 20 יולי 2007
Subject: Re: Query

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/




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


Reply via email to