M. Ilyas Hassan <[EMAIL PROTECTED]> wrote: : The input file is a flat file (.txt) parsed by "~" with 40 : columns. Columns 2-40 has numbers (all integers, +ve and -ve : numbers). Column 0 has items in alphanumeric and column 1 has : labels in text. I would like to find the minimum value for : numbers in columns 2-40 and write out an output in the form of : a flat file with 2 columns (col. 0 = item, col. 1 =min value).
That's 41 columns (0 - 40). 40 columns would be numbered 0 - 39. : Please see the code I wrote. I does NOT work. Thanks for your : input and help, Always begin your code with these modules. They will help you to use better programming habits. use strict; use warnings; : $i=0; Too early. Declare your variables when you use them. : open INV_RPT, "$_inventory_rpt" or die "Can't open file handler"; : open (INV_RPT_MIN, ">$_inventory_rpt_min"); $_inventory_rpt and $_inventory_rpt_min have not been defined. The first 'open' checks for errors and the second does not. Why? Be consistent. If you do error checking the first time, do it the last and every time in between. As long as you use perl you will be opening files. Create a macro for opening files in your code editor. Try to use the same open idiom each time. Including the $! variable will help you track down where errors came from. Here's mine. my $file = ''; open FH, $file or die qq(Cannot open "$file": $!); close FH; Whatever you choose, use the same thing for each 'open' statement. : { : chop($Ctmp1); : @Ctmp2=split(/~/,$Ctmp1); : $items{$Ctmp2[0]}=$Ctmp2[0]; : } Too early. $Ctmp1 (horrible name for a variable) has not been defined yet. The hash doesn't hold what you expect. Learn how to test. use Data::Dumper 'Dumper'; { chop($temp); @fields=split(/~/,$temp); $items{$fields[0]}=$fields[0]; } print Dumper \%items; __END__ I get: $VAR1 = { '' => undef }; So %items has one key with an undefined value. I am not sure what you intended to do here, but that wasn't it. : foreach $item (keys %items) : { The hash has one element. We can skip the loop and just write this. That doesn't look right, does it? my $item = ''; : while($Ctmp1 = <INV_RPT>) : { Under strict, that would be written like this. (Read perlfunc 'my') I used $record instead of $Ctmp1 because it is more descriptive of what the variable holds. Use meaningful variable names. while( my $record = <INV_RPT> ) { : chop($Ctmp1); "chop" is deprecated. Throw away whatever tool (book, tutorial, outdated program, etc,) you are using to learn perl. Go to learn.perl.org for books and online support for writing good perl scripts. chomp $record; : @Ctmp2=split(/~/,$Ctmp1); @Ctmp2 as used here has file scope. Let's scope it to this code block (using 'my') and let's use a meaningful name for it. my @fields = split /~/, $line; : $START_MIN{$ctmp2[0]}=$ctmp2[2]; Why does this hash (%START_MIN) use all caps for the the variable name? Other variables are mixed case (which I personally despise). What is so special about this hash that it should deserve all caps? According to your description we are attempting to find the minimum value in this array. We can do that by importing a function from List::Util. To import this function we need to "use" this module (at the beginning of the script). The function we need is named 'min'. use List::Util 'min'; : for $i (0..40) { Forty fields, not forty-one. foreach my $i ( 0 .. 39 ) { : if ( defined $fields[$i] ) { Every field in @fields will be defined. "split" cannot return undefined fields as it is used here. It *can* return empty fields (''). The only undefined fields are the fields added for columns with less than 40 columns. : $fields[$i] =~ s/\s*//; : } else { : $fields[$i] = ""; : } : } We could use this to eliminate the space between some negative numbers and the value. s/\s+//g foreach @fields; : if($START_MIN{$ctmp2[0]} < $Ctmp2[$i]) : { : $END_MIN{$Ctmp2[0]}=$Ctmp2[$i]; : print INV_RPT_MIN "$item~$END_MIN{$Ctmp2[0]}\n"; } : } You did say this code didn't work. Finding a minimum value in an array would require iterating over each element, not just these. We don't need any of that to get a minimum value with the imported min() function. my $item = shift @fields; s/\s+//g foreach @fields; my $minimum = min( @fields ); print INV_RPT_MIN "$item~$minimum\n"; : } : close(INV_RPT); : close(INV_RPT_MIN); : =============== As tested: use strict; use warnings; use List::Util 'min'; while ( <DATA> ) { my @fields = split /~\s*/; my $item = shift @fields; s/\s+//g foreach @fields; my $minimum = min( @fields ); print "$item~$minimum\n"; } __END__ AI6CQ7~Finishing Onhand~ 48.0~ 42.0~ 134.0~ 124.0~ 120.0~ 120.0~ 120.0~ 110.0~ 108.0~ 102.0~ 96.0~ 94.0~ 94.0~ 94.0~ 90.0~ 88.0~ 88.0~ 60.0~ 60.0~ 60.0~ 60.0~ 60.0~ - 48.0~ -34.0~ 24.0~ 18.0~ 18.0~ 18.0~ 14.0~ 98.0~ 88.0~ 88.0~ 88.0~ 88.0~ -88.0~ 82.0~ 78.0~ 68.0~ 62.0~ 58.0~ 58.0~ 58.0~ 56.0~ 50.0~ 44.0~ 42.0~ 40.0~ 140.0~ 140.0~ 96.0~ 96.0~ 96.0~ 96.0~ 96.0~ -96.0~ -96.0~ 56.0~ 56.0~ 56.0~ 56.0~ 56.0~ 56.0~ 56.0~ 56.0~ 56.0~ 56.0~ 56.0~ HTH, -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>