javpra has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

I'm new to Perl and have fallen in love with it as an all in one replacemnt for sh, sed, and awk. I am having trouble with getting the following line to work from within a script. How can this:

perl -F: -lane 'print $F[2]' checkstatres.txt

be made to work in a script. I tried the following, but it didn't work.

#!/usr/bin/perl use strict; use warnings; my @args; @args = ("cciss_vol_status /dev/ciss0 > checkstatres.txt"); open RESULTS, "checkstatres.txt" || die "can't open datafile: $!\n"; while (<RESULTS>){ 'print $F[2]'; }

Any help that this noob can be given is greatly appreciated.

Replies are listed 'Best First'.
Re: specific field selection
by Corion (Patriarch) on Mar 05, 2008 at 20:38 UTC

    I use the B::Deparse module to convert oneliners into scripts:

    perl -MO=Deparse -F: -lane "print $F[2]" checkstatres.txt

    gives me:

    BEGIN { $/ = "\n"; $\ = "\n"; } LINE: while (defined($_ = <ARGV>)) { chomp $_; our(@F) = split(/:/, $_, 0); print $F[2]; }

    as the basic script. Conversion to something usable likely is:

    #!/usr/bin/perl -w use strict; $/ = "\n"; $\ = "\n"; open my $fh, 'cciss_vol_status /dev/ciss0 |'; while (defined($_ = <$fh>)) { chomp $_; our(@F) = split(/:/, $_, 0); print $F[2]; }
Re: specific field selection
by NetWallah (Canon) on Mar 05, 2008 at 23:05 UTC
    • Your "open .. || die..." will NOT fail on open error, due to operator precedence. You can fix by:
      • using parens for the "open", or
      • using the "or" operator instead of "||"
    • add "my @F=split;" before your "print" to fix the problem you reported. This was being done for you by the perl "-a" option
    • Why is the "print" statement in quotes (single quotes)? That won't work. Please get rid of them.
    • "@args = ("cciss_vol_status /dev/ciss0 > checkstatres.txt");" is not doing anything. Please see the "system" operator if you want to run this.

         "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

      Thank you both so much. I'm impressed with the helpfulness and promptness of this forum. Below is the end result. Of course the last two printf() statements are kind of silly, I was just using them to make sure the script would work. Both of the printf() calls will be changed to system() in order to send out an email notification. There is no SMART equivelant for cciss drivers in FreeBSD so this will keep an eye on things.
      #!/usr/bin/perl use strict; use warnings; my @args; our $F; @args = ("cciss_vol_status /dev/ciss0 > checkstatres.txt"); system(@args); open RESULTS, "checkstatres.txt" or die "can't open datafile: $!\n"; while (<RESULTS>){ my @F=split(/:/, $_); if ( $F[2] =~ /OK./){ printf (" it's okay\n"); } else{ printf (" it's not ok\n"); } }
        In the spirit of helping improve programming skills, please accept these minor criticisms:

        • our $F; is not being used, and is not necessary. What IS being used it my @F...
        • You are separating the declaration and assignment of @args. Proficient perl programmers would combine these as in
          my @args = ("cciss_vol_status /dev/ciss0 > checkstatres.txt");
        • You are not checking to see if your system call was successful. Typical use is :
          system ... or die ....

        Happy programming!

        You could also consider the Net::SMTP (or Mail::SendEasy) modules as an alternative to using system calls to send mail.

             "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom