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

This is a slight expansion of an earlier problem which is getting a little annoying. When the following prints to the output a string of repeats occurs?
while (<FILE>) { #@outLines = (); ($etc,$etc) = split (/\s+/, $_) if (/^# input.*/); ($space, $Nd, $RES, $PDB, $val) = split (/\s+/, $_) if (/^\s\s\d+.*/); if (/^\s+\S+\s+\S+\s+$NUM17\b/) {$val = (split)[3]} elsif (/^\s+\S+\s+\S+\s+$NUM18\b/) {$va2 = (split)[3]} push (@outLines, $val); print OUT @outLines; }
output e.g 9.599.599.599.599.599.599.5 If were to put print "" outside while loops works fine for a single line in the input file, but need to loop through numerous times

Replies are listed 'Best First'.
Re: print to output problem
by Joost (Canon) on Jul 07, 2004 at 16:27 UTC
      adding one value to the end of the array - this is why i included just after the while(<FILE>) empty the array i am pushing onto?
        I think you'll find that # starts a comment. so that line doesn't do anything.

        Also, generally people will tell you to use strict; and use warnings; at the top of your code. which might give you some interesting hints.

        update: I don't think you really understand split either. type perldoc -f split, especially this section:

        In scalar context, returns the number of fields found a +nd splits into the @_ array. Use of split in scalar conte +xt is deprecated, however, because it clobbers your subroutin +e argu- ments. If EXPR is omitted, splits the $_ string. If PATTERN i +s also omitted, splits on whitespace (after skipping any leadi +ng whitespace). Anything matching PATTERN is taken to be +a delim- iter separating the fields. (Note that the delimiter m +ay be longer than one character.)
Re: print to output problem
by sweetblood (Prior) on Jul 07, 2004 at 16:30 UTC
    You want the print statement outside of your while loop
    push (@outLines, $val); } print OUT @outLines;
    Otherwise it print the contents of @outLines for each line
    HTH

    Sweetblood

      i have multiple entries in my input file to look at, so if i was to print outside the while loop, surely i will only be printing the last loop through the input?
        here is my input file:
        # input for ....find 17th and 18th number # input for .... again Nd RES PDB val 1 140 31 20.0 1 142 33 0.0 1 143 34 10.0 1 144 35 0.0
        say 17th number is 143, would print out 10 on first loop then say 17th number is 140 would print 20 on second
Re: print to output problem
by Roy Johnson (Monsignor) on Jul 07, 2004 at 17:20 UTC
    Does this do what you want?
    while (<FILE>) { undef $val; if (/^# input/) { ($etc) = (split)[1] } elsif (/^\s\s\d+/) { ($space, $Nd, $RES, $PDB, $val) = split } elsif /^\s.*$NUM17\b/) { $val = (split)[3] } elsif /^\s.*$NUM18\b/) { $va2 = (split)[3] } if (defined $val) { push(@outlines, $val); print $val; } }

    We're not really tightening our belts, it just feels that way because we're getting fatter.
      thanks for the effort Roy but still only prints the last $val?
        It looks like you need to store up your $NUM17 values in an array, and you also need to store up your RES-val pairs in a hash. Then, after you've read and stored the whole mess, go through the array and print the corresponding hash values. Like:
        my @requests = (); my %lookups = (); while (<FILE>) { if (/^# input/) { push @requests, (split)[1]; } elsif (/^\s\s\d+/) { my ($RES, $val) = (split)[2,4] $lookups{$RES} = $val; } } print join("\n", @lookups{@requests}), "\n";
        It's not clear to me what the $NUM17 and $NUM18 business is all about, or what $etc is for. What I've done is assume that $etc indicates which $RES to look for, to print the associated $val.

        We're not really tightening our belts, it just feels that way because we're getting fatter.
Re: print to output problem
by dws (Chancellor) on Jul 07, 2004 at 16:46 UTC

    If you really intend to discard part of the result of a split, it's clearer to write

    (undef, $etc) = split(/\s+/, $_) if (/^# input.*/);
    than to write
    ($etc,$etc) = split (/\s+/, $_) if (/^# input.*/);
      i know it returning the correct value by using
      print OUT (split)[3], "\n" if /^\s+\S+\s+\S+\s+$NUM17\b/;
      its just the fact that the out puts are all strings of the same answer
Re: print to output problem
by Roy Johnson (Monsignor) on Jul 07, 2004 at 16:52 UTC
    You just want to print $val within the loop.

    We're not really tightening our belts, it just feels that way because we're getting fatter.
Re: print to output problem
by gellyfish (Monsignor) on Jul 07, 2004 at 16:59 UTC

    The only times $val is assigned to it is conditional upon the input and at no point are you resetting the value of $val, therefore if the first line matches and no further lines do then $val will retain the same value and @outlines will be populated with identical values.

    /J\

      also tried this ealrier on along with cleaning the @outLines oout, but still returns the last output only
Re: print to output problem
by Anonymous Monk on Jul 07, 2004 at 16:21 UTC
    #@outLines = (); no hash!