Appending a character to a field

B

bokjasong

Hi,


I'm a perl newbie and would like to ask this question.

Let's say I have the following code. Trying to check the disk space,
it's to truncate the percent sign % from the df -k output, compare the
percentage field to see if it's bigger than 90%, and grasp only those
lines that are and push those to an array @df. But how can I add the
percentage sign back to the percentage field on each line for the
proper output? I put down ??????? as below to find out what regexp
needs to be there in the below.


$percent=90;

open(DFOUT, "/usr/bin/df -k|");
while (<DFOUT>) {
next if ($_ =~ /Filesystem/i);
s/\%//; # to remove the percent sign for comparison
if ( (split)[4] >= $percent ) {
???????
push(@df, $_);
}
}

print "@dfoutput\n";



I appreciate your help very much!

Thank you.


- Bok
 
I

it_says_BALLS_on_your forehead

Hi,

I'm a perl newbie and would like to ask this question.

Let's say I have the following code. Trying to check the disk space,
it's to truncate the percent sign % from the df -k output, compare the
percentage field to see if it's bigger than 90%, and grasp only those
lines that are and push those to an array @df. But how can I add the
percentage sign back to the percentage field on each line for the
proper output? I put down ??????? as below to find out what regexp
needs to be there in the below.

$percent=90;

open(DFOUT, "/usr/bin/df -k|");
while (<DFOUT>) {
next if ($_ =~ /Filesystem/i);
s/\%//; # to remove the percent sign for comparison
if ( (split)[4] >= $percent ) {
???????
push(@df, $_);
}

}

print "@dfoutput\n";

How about instead of removing the '%' sign in the first place, you
pass a copy of (split)[4] as a parameter to a subroutine, then chop it
off there to do your compare, and return true or false from the
subroutine to determine whether or not you should push into your @df
array?
 
J

Jürgen Exner

Hi,


I'm a perl newbie and would like to ask this question.

Let's say I have the following code. Trying to check the disk space,
it's to truncate the percent sign % from the df -k output, compare the
percentage field to see if it's bigger than 90%, and grasp only those
lines that are and push those to an array @df. But how can I add the
percentage sign back to the percentage field on each line for the
proper output? I put down ??????? as below to find out what regexp
needs to be there in the below.

Just plain ignore the % sign. When evaluating a text in numerical context
then Perl will take any leading number as the value and happily ignore any
trailing non-numbers (somewhat simplified, but shouldn't matter in your
case).
$percent=90;
open(DFOUT, "/usr/bin/df -k|");
while (<DFOUT>) {
next if ($_ =~ /Filesystem/i);
s/\%//; # to remove the percent sign for comparison

Just get rid of this substitute line.
if ( (split)[4] >= $percent ) {

Then this comparison should work just automagically.

jue
 
B

Ben Morrow

Quoth "Jürgen Exner said:
Just plain ignore the % sign. When evaluating a text in numerical context
then Perl will take any leading number as the value and happily ignore any
trailing non-numbers (somewhat simplified, but shouldn't matter in your
case).

This ignores the fact that Perl will warn if a string has trailing
non-numeric characters. This warning can be suppressed for a block with

no warnings 'numeric';

You should always check the return value of open.
You should probably use lexical filehandles.
You should probably use 3-arg open, as its safer.

open(my $DFOUT, '-|', '/usr/bin/df', '-k')
or die "cannot run df: $!";

$_ is implicitly used by the match operators, so

next if /Filesystem/i;
s/\%//; # to remove the percent sign for comparison

Just get rid of this substitute line.
if ( (split)[4] >= $percent ) {

Then this comparison should work just automagically.

To add the % back on, the simplest means is to push "$_%" onto your
array instead of $_. A better answer may be to use the Filesys::Df or
Filesys::DfPortable module, and get the information straight from
statvfs(2) without needing to invoke df(1).

Ben
 
J

John W. Krahn

Ben said:
This ignores the fact that Perl will warn if a string has trailing
non-numeric characters. This warning can be suppressed for a block with

no warnings 'numeric';


You should always check the return value of open.
You should probably use lexical filehandles.
You should probably use 3-arg open, as its safer.

open(my $DFOUT, '-|', '/usr/bin/df', '-k')
or die "cannot run df: $!";

And with a piped open you should also check the return value of close:

perldoc -f close



John
 
B

bokjasong

Hi Ben,

Thanks for your various suggestions. I embedded all of them into my
code but I cannot figure out how to push "$_%" onto my array. I keep
getting some syntax error when I tried with push(@df, $_%). Could you
give me some example?

Thank you.

- Bok
 
B

bokjasong

Hi Jurgen,


Thanks for your suggestion but I need to add the % sign back to the
5th field of the df output. If I do print "$_%" then I think % will be
appended to the very last field for the filesystem mount points.

- Bok
 
J

Jürgen Exner

Thanks for your suggestion but I need to add the % sign back to the
5th field of the df output.

Dude,

besides the different function do you notice any other difference between
push(@df, $_%)
and
print "$_%"

Hint: how do you denote a string with variable interpolation?

Oh, and BTW:
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

jue
 
B

bokjasong

Dude,

besides the different function do you notice any other difference between
push(@df, $_%)
and
print "$_%"

Hint: how do you denote a string with variable interpolation?

Oh, and BTW:
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

jue


Jue,

I didn't clearly specify and simplified the last part with a print but
I push $_ to @df and then have another block that follows, which is
outside the while loop, to send @df by sendmail, so I need to take
care of @df inside the while loop with % added back.

Thanks.

- Bok
 
A

Anno Siegel

Hi,


I'm a perl newbie and would like to ask this question.

Let's say I have the following code. Trying to check the disk space,
it's to truncate the percent sign % from the df -k output, compare the
percentage field to see if it's bigger than 90%, and grasp only those
lines that are and push those to an array @df. But how can I add the
percentage sign back to the percentage field on each line for the
proper output? I put down ??????? as below to find out what regexp
needs to be there in the below.


$percent=90;

open(DFOUT, "/usr/bin/df -k|");
while (<DFOUT>) {
next if ($_ =~ /Filesystem/i);
s/\%//; # to remove the percent sign for comparison
if ( (split)[4] >= $percent ) {
???????
push(@df, $_);
}
}

print "@dfoutput\n";

You can use the percent character to single out the number without
removing it.

my $percent = 90;

my @dfoutput;
open(DFOUT, "/bin/df -k|");
while (<DFOUT>) {
my $perc_full;
next unless ( $perc_full) = /(\d+)%/ and $perc_full >= $percent;
push @dfoutput, $_;
}

print "@dfoutput\n";


or, more compact:

my @dfoutput = grep {
my $perc_full;
( $perc_full) = /(\d+)%/ and $perc_full >= $percent;
} `/bin/df`;

It skips lines that have no "%" (the header line) and those that are below
the percentage limit.

Anno
 
J

Jürgen Exner

I didn't clearly specify and simplified the last part with a print but
I push $_ to @df and then have another block that follows, which is
outside the while loop, to send @df by sendmail, so I need to take
care of @df inside the while loop with % added back.

Ok, ok, spoonfeeding:

C:\tmp>type t.pl
push (@df, $_%);
C:\tmp>perl -c t.pl
syntax error at t.pl line 1, near "%)"
t.pl had compilation errors.

C:\tmp>type t.pl
push (@df, "$_%");
C:\tmp>perl -c t.pl
t.pl syntax OK

Do you see the difference now?

Aside of that IMNSHO you are still going about your general task in a very
odd way.
Several people have pointed out different and IMO much better ways to
compare the percentage value.

I am asking again: what about simply ignoring the percentage sign? Perl will
take care of the value automatically:

my $limit = 90;
my @df = ('80%', '95%', '7%', '100%', 'garbage');
for (@df) {
print "$_\n" if $_ > $limit;}

prints

95%
100%

just as you would expect. Sure, you have to disable warnings in that block,
because otherwise you will get a "Argument ... isn't numeric" warning. But
so what?

jue
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top