<?xml version="1.0" encoding="windows-1252"?>
<node id="1002964" title="My first perl script is working, what did I do wrong?" created="2012-11-08 14:30:46" updated="2012-11-08 14:30:46">
<type id="115">
perlquestion</type>
<author id="1002937">
killersquirel11</author>
<data>
<field name="doctext">
&lt;p&gt;Hey all,&lt;/p&gt;

&lt;p&gt;I've hacked a few perl scripts in my day, but this is the first time I've ever written one from scratch.  Thus I want to get some feedback on the good, the bad, and the ugly of what I've done here&lt;/p&gt;

&lt;p&gt;Essentially, the script's job is to parse a file containing a column of part names and several columns of description (the columns are fixed-width space-delimited), and output how many parts match each description.  Below is the code:&lt;/p&gt;

&lt;code&gt;
#!/usr/bin/perl -w

use strict;
use warnings;

print "ARGV: $#ARGV\n";

if ($#ARGV != 0) {
     print "One, and only one (not $#ARGV), command line parameter is expected\n";
     exit;
}
my $inputFile=$ARGV[0];

if ( not -e $inputFile) {
     die "$inputFile doesn't exist!!!\nExiting.\n";
}

print "Attempting to open $inputFile\n";

open my $file, $inputFile or die "Could not open $inputFile: $!";
my $headerLine= -1;
my $prtIndex  = -1;
my $shpIndex  = -1;
my $clrIndex  = -1;
my $sizIndex  = -1;
my %values    = ();
my $index     =  0;
my @parts     = ();
while( my $line = &lt;$file&gt;) {
    if ( $line =~ "Part *Shape *Color *Size" ){
        if($headerLine &lt; 0){
            $headerLine=$.;
            $prtIndex=index $line, "Part";
            $shpIndex=index $line, "Shape";
            $clrIndex=index $line, "Color";
            $sizIndex=index $line, "Size";
        }
        next
    }
    if(not checkIndices($prtIndex, $shpIndex, $clrIndex, $sizIndex)){
        $headerLine=-1;
        next;
    }
    if(length($line)&lt;$sizIndex){
        next;
    }
    my $prt = substr $line, $prtIndex, $shpIndex-1-$prtIndex;
    my $shp = substr $line, $shpIndex, $clrIndex-1-$shpIndex;
    my $clr = substr $line, $clrIndex, $sizIndex-1-$clrIndex;
    my $siz = substr $line, $sizIndex;
    trimall($prt,$shp,$clr,$siz);
    my $superstr=$shp.$clr.$siz;
    if(not exists $values{$superstr}){
        $values{$superstr}=$index;
        $parts[$index][0][0]=$prt;    #List of all parts
        $parts[$index][1]=$superstr;  #Value of the parts
        $parts[$index][2]=1;          #Total qty of these parts
        $index++;
    } else {
        my $i=$values{$superstr};
        $parts[$i][0][$parts[$i][2]] = $prt;
        $parts[$i][2]++;
    }
}

for my $i (0..$index-1){
    my @plist=$parts[$i][0];
    my $value=$parts[$i][1];
    my $count=$parts[$i][2];
    for my $j (0..$parts[$i][2]-1){
        printf $parts[$i][0][$j]." ";
    }   printf "- ";
    print $value." - ";
    print $count.".\n";
}
exit;

# Check if the indices for a number of input variables are all &gt;= 0
sub checkIndices {
    my $count;
    for ($count=0; $count&lt;=$#_; $count++){
        if($_[$count] &lt; 0){
            return (1==0);
        }
    }
    return (1==1);
}

# Remove leading and trailing whitespace from all arguments
sub trimall {
    my $count;
    for ($count=0; $count&lt;=$#_; $count++){
        $_[$count] =~ s/^\s*//; $_[$count] =~ s/\s*$//;
    }
    return;
}

&lt;/code&gt;

&lt;p&gt;&lt;br&gt;And here is the test input file&lt;/p&gt;
&lt;code&gt;
Part     Shape      Color   Size
P1       Circle     Red     1   
P2       Square     Green   3   
P3       Rectangle  Red     4   
P4       Circle     Red     1   
P5       Square     Blue    1   
P6       Square     Green   3   
P7       Rectangle  Blue    4   
P8       Square     Red     2   
P9       Circle     Green   3   
P10      Circle     Blue    4   
&lt;/code&gt;
&lt;p&gt;&lt;br&gt;When all is said and done, it should output that P1 and P4 are equal, as are P2 and P6, which it does:&lt;/p&gt;
&lt;code&gt;
ARGV: 0
Attempting to open testFile.txt
P1 P4 - CircleRed1 - 2.
P2 P6 - SquareGreen3 - 2.
P3 - RectangleRed4 - 1.
P5 - SquareBlue1 - 1.
P7 - RectangleBlue4 - 1.
P8 - SquareRed2 - 1.
P9 - CircleGreen3 - 1.
P10 - CircleBlue4 - 1.
&lt;/code&gt;
&lt;p&gt;&lt;br&gt;So now, I ask of ye, oh keepers of the &lt;strike&gt;Scrolls&lt;/strike&gt; Scripts, what you would change about my work?&lt;/p&gt;
&lt;p&gt; Thanks in advance! &lt;/p&gt;</field>
</data>
</node>
