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

I have the following output in a file called graph_set.txt

POLYMORPH 1
C 1, 1( 9)
C 2, 2(11)
R 2, 2(18)

POLYMORPH 2

POLYMORPH 3
C 1, 1( 4)
C 2, 2(18)
C 1, 1( 4)
R 2, 2(18)

POLYMORPH 4
C 1, 1( 9)
C 2, 2(18)
C 1, 1( 9)
R 2, 2( 8)

POLYMORPH 5
C 1, 1( 0)
C 1, 1( 0)
C 1, 1( 9)
C 2, 2(18)
etc....etc
I wish to do a while loop to extract the data after each title POLYMORPH n
I written the code below, but not working ? I think its the stuff after the if command thats not right ? could someone please help me correct the mistake i've made

$in_filename = "graph_set.txt"; open (IN,"$in_filename") or die "Can't open $in_filename:$!\n"; my $i; LOOP: while (<IN>) { if (/POLYMORPH/) { my $tmps = <IN>; ($final_gset[$i]), $tmps; } } close (IN); open (TEXT, ">>test.txt") or die "Can't create test.txt: $!\n"; foreach $_(@final_gset) { print TEXT "$_\n"; } close TEXT;

Replies are listed 'Best First'.
Re: while loop not working
by Skeeve (Parson) on Jul 15, 2003 at 10:57 UTC
    First of all you don't increment your $i

    Then... What should ($final_gset[$i]), $tmps; do? I think you mean:

    $final_gset[$i]= $tmps;
    don't you?

    But what's the stop condition? Maybe this is, what you need:

    while (<IN>) { if ($hit=/POLYMORPH/ ... /^\s*$/) { # This will be reached for each line from # POLIMORPH to the next empty line (including) # In order to exclude the first (POLYMORPH) # and the last (empty) line, we do next if $hit==1 || $hit=~/e0/i; # If we gut a line of data, we append them # to our array push(@final_gset, $_); # and get the next line next; } # This will be reached for anything else }
    Your foreach-loop can be shortened to:
    print TEXT join("\n",@final_gset),"\n";
Re: while loop not working
by BrowserUk (Patriarch) on Jul 15, 2003 at 11:00 UTC

    Could you describe what it is that you are trying to do?

    It looks like you are simply reading everything from one file and then appending it to another? Going by the output filename this is just a test, but if that is your intention , then an OS command would achieve this much more easily.

    With regard to the body of the if statement, you are only reading one line after the section header. Is this your intent?

    And if the intent of this line

    ($final_gset[$i]), $tmps;

    is to assign the line you read in, into an element of the array, then where is the assignment? Ie. '='.

    Basically, theere is no need to assign to a temporary var and then to the array, you might as well do this directly

    if (/POLYMORPH/) $final_gset[$i] = <IN>; }

    If that is your intent, then the other problem with your code is that you are never incrementing $i, so you are always over the same element. Except, that you have never assigned a value to $i, so it has the value undef, which is illegal as an array subscript.

    If you had

    use strict; use warnings;

    at the top of your program, Perl would have probably told you most of this.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller

      basically i'm trying to loop so each time POLYMORPH is seen the data below is read and outputed to a txt file. This code does not seem to read or print all the data. i'ts printing out some of the data from each polymorph ?. is there something wrong ?
      my $i; my @final_gset = (); LOOP: while (<IN>) { if (/POLY/) { $final_gset[$i] = <IN>; $i++; next LOOP; } } close (IN); open (TEXT, ">>test.txt") or die "Can't create test.txt: $!\n"; foreach $_(@final_gset) { print TEXT "$_"; } close TEXT;

        The problem is that you seem to be aware that

        while( <IN> ) {...

        reads a single line, hence you need to loop back to read the next one, but then when you get to

        if(/POLY/) { $final_gset[$i] = <IN>; ...

        you seem to be expecting that line to somehow magically read multiple lines. It won't.

        I might go into a more detailed explanation, but I still think that you don't need to write this program. You are (trying to ) read all the lines from one file and then append them to another. This would be much more easily accomplished using

        C:\> type graph_set.txt >>test.txt

        or$ cat graph_set.txt >>test.txt

        depending which view of the world you see as being rightous:)


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller

        is there something wrong ?

        Yes. You say that you want the data below POLYMORPH. Your code does not do that.

        Perhaps an alternative approach is to load the contents of your input file into a scalar, split the scalar on 'POLYMORPH', and then if it is neccessary to tweak it further perform some regexes on the resulting list, before dumping it to your output file.

        I hope this helps

Re: while loop not working
by LTjake (Prior) on Jul 15, 2003 at 11:44 UTC

    If all you want to do is capture all lines that aren't blank and don't containt POLYMORPH, then just tell perl to do that:

    my @data; while( <IN> ) { chomp; push @data, $_ unless /^\s*$/ or /^POLYMORPH/; }

    Using Data::Dumper this gave me:

    $VAR1 = [ 'C 1, 1( 9)', 'C 2, 2(11)', 'R 2, 2(18)', 'C 1, 1( 4)', 'C 2, 2(18)', 'C 1, 1( 4)', 'R 2, 2(18)', 'C 1, 1( 9)', 'C 2, 2(18)', 'C 1, 1( 9)', 'R 2, 2( 8)', 'C 1, 1( 0)', 'C 1, 1( 0)', 'C 1, 1( 9)', 'C 2, 2(18)' ];

    You may want something more complex than that...

    --
    "To err is human, but to really foul things up you need a computer." --Paul Ehrlich