For Programmers: Free Programming Magazines  


Home > Archive > PERL Miscellaneous > August 2007 > Appending a character to a field









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Appending a character to a field
bokjasong@gmail.com

2007-08-29, 10:03 pm



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

it_says_BALLS_on_your forehead

2007-08-29, 10:03 pm

On Aug 29, 4:22 pm, bokjas...@gmail.com wrote:
> 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ürgen Exner

2007-08-29, 10:03 pm

bokjasong@gmail.com wrote:
> 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


Ben Morrow

2007-08-29, 10:03 pm


Quoth "Jürgen Exner" <jurgenex@hotmail.com>:
> bokjasong@gmail.com wrote:
>
> 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: $!";
[color=darkred]

$_ is implicitly used by the match operators, so

next if /Filesystem/i;
[color=darkred]
>
> Just get rid of this substitute line.
>
>
> 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

John W. Krahn

2007-08-29, 10:04 pm

Ben Morrow wrote:
> Quoth "Jürgen Exner" <jurgenex@hotmail.com>:
>
> 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
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
bokjasong@gmail.com

2007-08-30, 7:55 pm



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


> 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ürgen Exner

2007-08-30, 7:55 pm

bokjasong@gmail.com wrote:
> getting some syntax error when I tried with push(@df, $_%). Could you
> give me some example?


$_ = 'whatever';
print "$_%";

jue


bokjasong@gmail.com

2007-08-30, 7:55 pm



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


On Aug 30, 8:45 am, "J=FCrgen Exner" <jurge...@hotmail.com> wrote:
> bokjas...@gmail.com wrote:
>
> $_ =3D 'whatever';
> print "$_%";
>
> jue



Jürgen Exner

2007-08-30, 7:55 pm

bokjasong@gmail.com wrote:
> On Aug 30, 8:45 am, "Jürgen Exner" <jurge...@hotmail.com> wrote:
> 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


bokjasong@gmail.com

2007-08-30, 7:55 pm

On Aug 30, 9:11 am, "J=FCrgen Exner" <jurge...@hotmail.com> wrote:
> bokjas...@gmail.com wrote:
>
>
>
> 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



Anno Siegel

2007-08-30, 7:55 pm

On 2007-08-29 22:22:31 +0200, bokjasong@gmail.com said:

>
>
> 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ürgen Exner

2007-08-30, 7:55 pm

bokjasong@gmail.com wrote:
> On Aug 30, 9:11 am, "Jürgen Exner" <jurge...@hotmail.com> wrote:
>
> 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


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com