Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

My first Perl : need a look over it for problems/bugs/errors

Status
Not open for further replies.

browserice

Technical User
Aug 20, 2006
21
US
I am coding my first Perl script. It reads an input file produced from a tivoli "wmonpln -l" command and redirecting it to another file but in a comma seperated record to be used by other sets of tools.

1) The input (I don't know how) should be from the pipe. Right now, I put down a file just for the testing purposes but need it to be from a pipe (xxxx >myperl.pl).

2) if there are 9 fields, then comma seperate all fields into a string and output it

3) if there are 10 fields, then 2 fields need to be combined and then comma seperate all fields into a string to then output it

Now with this input info, here is my perl script below. When I ran it, it displayed in console, lines with one long integer (I don't know why). I added print cmds for debuging infos but I still have no clues :

#!/usr/bin/env perl
#
#====================================================================================
# name : CleanPlanOutput.pl
# version : Beta 1.0
# language: Perl
# Created by : me
# Created on : Aug-20, 2006
# Description : takes the wmonplan output and re-outputs it in comma seperated fields
# to be used by any other scripts. Takes in account the status that can
# be 2 words or not.
#=======================================================================================================================================================================
#<-----PlanID------> ReturnCode <--Status------> <-------PlanName-----------------------------------------------------------> <----StartedAt----> <------EndedAt----->
#1155772582033163865 0 Canceled Pending UK_REM_EMD_ms_std_hotfix_sequence_NET_part1_ALL_2006-08-15@08/17/06 01:56:22 2006-08-17 01:56:22 2006-08-18 01:58:21
#Field#0 1 2 3 4 5 6 7 8 9
#1155772659085890842 0 Canceled UK_REM_EMD_ms_std_hotfix_sequence_NET_part2_ALL_2006-08-15@08/17/06 01:57:39 2006-08-17 01:57:39 2006-08-18 02:00:34
#Field#0 1 2 3 4 5 6 7 8
#=======================================================================================================================================================================
#initializations

#open input file
open(INFILE,"wmonpln.tmp") or die "Cannot open CleanPlanOutput input!";

#open output file
open(OUTFILE,">CleanPlanOutput.pl.tmp") or die "Cannot open CleanPlanOutput output!";

#open output log file
open(LOGFILE,">CleanPlanOutput.pl.log") or die "Cannot open CleanPlanOutput Log file!";

print "Starting...\n";

#while input file not empty
while (<INFILE>) {
# reads a record
my $InputRec=<INFILE>;
print "reading:"+$InputRec+"\n";

# parse fields into array
@fields=split(" ",$InputRec);

# is there 9 fields ?
if ( @fields==9 ) {
# then status should be one word only, get all 9 fields
print "9 fields found\n";
$OutputRec=@fields[0]+","+@fields[1]+","+@fields[2]+","+@fields[3]+@fields[4]+",";
$OutputRec=$OutputRec+@fields[5]+@fields[6]+","+@fields[7]+@fields[8];
} elsif ( @fields==10 && @fields[3]=="Pending" ) {
# otherwise, is there 10 fields ?
# then status should be 2 words, get all 10 fields
print "10 fields found\n";
$OutputRec=@fields[0]+","+@fields[1]+","+@fields[2]+@fields[3]+",";
$OutputRec=$OutputRec+@fields[4]+@fields[5]+","+@fields[6]+@fields[7]+",";
$OutputRec=$OutputRec+@fields[8]+@fields[9];
} else {
# otherwise, we have a faulty record ?
print "non standard record found\n";
$OutputRec="";
print LOGFILE $InputRec;
}
# output the record in right order
print OUTFILE $OutputRec;
}
#close input
close INFILE;

#close output
close OUTFILE;
close LOGFILE;
 
lots of problems in your script, might be easier just to post code and you can ask questions if needed:

Code:
#!/usr/bin/env perl
use strict;
use warnings;
#open input file
open(INFILE,"wmonpln.tmp") or die "Cannot open CleanPlanOutput input!";

#open output file
open(OUTFILE,">CleanPlanOutput.pl.tmp") or die "Cannot open CleanPlanOutput output!";

#open output log file
open(LOGFILE,">CleanPlanOutput.pl.log") or die "Cannot open CleanPlanOutput Log file!";

while (my $InputRec=<INFILE>) {
   my $OutputRec = '';
   print "reading:"+$InputRec+"\n";
   my @fields=split(/\s+/,$InputRec);
   if ( @fields == 9 ) {
      # then status should be one word only, get all 9 fields
      print "9 fields found\n";
      $OutputRec = join(',',@fields[0..8]);
      print OUTFILE "$OutputRec\n";
   }
   elsif ( @fields == 10 && $fields[3] eq "Pending" ) {
      # otherwise, is there 10 fields ?
      # then status should be 2 words, get all 10 fields
      print "10 fields found\n";
      $OutputRec = join(',',@fields[0..9]);
      print "$OutputRec\n";
   }
   else {
      # otherwise, we have a faulty record ?
      print "non standard record found\n";
      print LOGFILE "$InputRec\n";
   }
}
#close input
close INFILE;

#close output
close OUTFILE;
close LOGFILE;
 

Been doing some Java/other language lately, Kev? ;-)
Code:
   print "reading:"+$InputRec+"\n";

@browserice - two things spring to mind straight away when I look at your code.

The concatenation operator (to stick strings together) in Perl is a dot, not a plus, i.e.:
Code:
   print "reading:".$InputRec."\n";
   # or just
   print "reading: $InputRec\n";

Also, when referring to single elements of an array, use a $ rather than a @, i.e.:
Code:
    } elsif ( @fields==10 && $fields[3]=="Pending" ) {
Kevin made that change, but I just thought I'd point it out to you specifically.
 
Thank you but 2 things :

1) I don't simply want to put your changes into my code. I need to understand why the differences. Explanations should always be put on any code changes. I need to understand before I do anything.

2) I don't simply concatenate all fields back together. Not all fields are comma seperated. Some fiels need to be joined then the result being comma seperated.

if 10 fields, then result has to be :
"field#0,#1,#2 #3,#4 #5,#6 #7,#8 #9"

if 9 fields, then result has to be :
"field#0,#1,#2,#3 #4, #5 #6, #7 #8"


Anyway, in the mean time that I get an answer, I'll look it up and play with it. Thanks.
 
been doing some Java/other language lately, Kev?

I missed that one, seems you missed this one:

Also, when referring to single elements of an array, use a $ rather than a @, i.e.:

Code:
    } elsif ( @fields==10 && [b]$fields[3]=="Pending"[/b] ) {

but knowing perl it probably works with '==' instead of 'eq' :)
 
Oh and also, you guys didn't tell me how I can have the input coming from the pipe and not from a file.
 
if 10 fields, then result has to be :
"field#0,#1,#2 #3,#4 #5,#6 #7,#8 #9"

then do like this:

Code:
$OutputRec = join(',',@fields[0..1],"$fields[2] $fields[3]",@fields[4..9]);
 
oops. I messed that up, should be:


Code:
$OutputRec = join(',',@fields[0..1],"$fields[2] $fields[3]","$fields[4] $fields[5]","$fields[6] $fields[7]","$fields[8] $fields[9]");

or you could just do it like this:

Code:
$OutputRec = "$fields[0],$fields[1],$fields[2] $fields[3],$fields[4] $fields[5],$fields[6] $fields[7],$fields[8] $fields[9]";
 
Thank you very much.

What about having the input from the pipe ?
 
from the Perl CookBook:

16.1. Gathering Output from a Program

Problem

You want to run a program and collect its output into a variable.

Solution

Either use backticks:

Code:
$output = `program args`;   # collect output into one multiline string
@output = `program args`;   # collect output into array, one line per element

Or use Recipe 16.4:

Code:
open(README, "program args |") or die "Can't run program: $!\n";
while(<README>) {
    $output .= $_;
}
close(README);
 
Suggest using the backticks or qx to get the output of the tivoli command into an array to avoid the pipe.
Code:
my @stuff = qx[wmonpln -l];
foreach (@stuff) {
   # your code here
}
Are there any other switches you can supply to the tivoli command to make the output easier to parse? Like suppressing headings, totals etc?

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top