Appending a character to a field

Discussion in 'Perl Misc' started by bokjasong@gmail.com, Aug 29, 2007.

  1. Guest

    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
    , Aug 29, 2007
    #1
    1. Advertising

  2. On Aug 29, 4:22 pm, 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?
    it_says_BALLS_on_your forehead, Aug 29, 2007
    #2
    1. Advertising

  3. 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
    Jürgen Exner, Aug 29, 2007
    #3
  4. Ben Morrow Guest

    Quoth "Jürgen Exner" <>:
    > wrote:
    > >
    > > 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).


    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';

    > > $percent=90;
    > > open(DFOUT, "/usr/bin/df -k|");


    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: $!";

    > > while (<DFOUT>) {
    > > next if ($_ =~ /Filesystem/i);


    $_ 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
    Ben Morrow, Aug 29, 2007
    #4
  5. Ben Morrow wrote:
    > Quoth "Jürgen Exner" <>:
    >> wrote:
    >>> 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).

    >
    > 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';
    >
    >>> $percent=90;
    >>> open(DFOUT, "/usr/bin/df -k|");

    >
    > 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
    John W. Krahn, Aug 30, 2007
    #5
  6. Guest

    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
    , Aug 30, 2007
    #6
  7. wrote:
    > getting some syntax error when I tried with push(@df, $_%). Could you
    > give me some example?


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

    jue
    Jürgen Exner, Aug 30, 2007
    #7
  8. Guest

    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ürgen Exner" <> wrote:
    > wrote:
    > > getting some syntax error when I tried with push(@df, $_%). Could you
    > > give me some example?

    >
    > $_ = 'whatever';
    > print "$_%";
    >
    > jue
    , Aug 30, 2007
    #8
  9. wrote:
    > On Aug 30, 8:45 am, "Jürgen Exner" <> wrote:
    >> wrote:
    >>> getting some syntax error when I tried with push(@df, $_%). Could
    >>> you give me some example?

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

    > 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
    Jürgen Exner, Aug 30, 2007
    #9
  10. Guest

    On Aug 30, 9:11 am, "Jürgen Exner" <> wrote:
    > wrote:
    > > On Aug 30, 8:45 am, "Jürgen Exner" <> wrote:
    > >> wrote:
    > >>> getting some syntax error when I tried with push(@df, $_%). Could
    > >>> you give me some example?

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

    >
    > > 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



    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
    , Aug 30, 2007
    #10
  11. Anno Siegel Guest

    On 2007-08-29 22:22:31 +0200, 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
    Anno Siegel, Aug 30, 2007
    #11
  12. wrote:
    > On Aug 30, 9:11 am, "Jürgen Exner" <> wrote:
    >> wrote:
    >>> On Aug 30, 8:45 am, "Jürgen Exner" <> wrote:
    >>>> wrote:
    >>>>> getting some syntax error when I tried with push(@df, $_%). Could
    >>>>> you give me some example?

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

    >>
    >>> 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?

    >
    > 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
    Jürgen Exner, Aug 30, 2007
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Velvet
    Replies:
    9
    Views:
    14,814
    Joerg Jooss
    Jan 19, 2006
  2. raavi
    Replies:
    2
    Views:
    909
    raavi
    Mar 2, 2006
  3. Sound
    Replies:
    2
    Views:
    439
    Randy Webb
    Sep 28, 2006
  4. Mechphisto
    Replies:
    3
    Views:
    74
    Thomas 'PointedEars' Lahn
    Jan 13, 2009
  5. jr
    Replies:
    3
    Views:
    418
Loading...

Share This Page