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

Okay, say this is basicdez.dat file.
"PER" "Denise Johnson" "red,orange,yellow,green,blue,purple" 09/25/2001 "EOS"
And this is the desired outcome...
Name = Denise Johnson Color = red Color = orange Color = yellow Color = green Color = blue Color = purple Date = 09/25/2001
How could I change this code to read in the colors as an array. I do not want this...
Name = Denise Johnson Color = red,orange,yellow,green,blue,purple Date = 09/25/2001
And I do not want this, which is what this code currently produces...
Name = PER Color = Date = Name = Denise Johnson Color = red,orange,yellow,green,blue,purple Date = 09/25/2001
I would like to take the colors in as a comma delimitted field and produce them out as individual fields. Please help me if you can. peace dez L Current Code (It really needs some help)
#!/usr/bin/perl-Tw use strict; use Text::ParseWords; open(DATA,"basicdez.dat") || die "Cannot open datfile: $!\n"; my @data; my $i = 0; while (<DATA>) { chomp; last if /^"EOS"$/; { @data = &quotewords('\s+', 0, $_); } print "Name = $data[0]\n"; print "Color = $data[1]\n"; print "Date = $data[2]\n"; }
I know that this does not come close, but please help me out if you can... What I really need help with is seperating out the comma dilemmeted field. Any suggestions would be awesome... dez L

Replies are listed 'Best First'.
Re: Comma Delimitted Fields..
by thatguy (Parson) on Oct 18, 2001 at 23:53 UTC
    split the color field ($data[1]) into an array and the print the colors like so:
    #!/usr/bin/perl-Tw use strict; use Text::ParseWords; open(DATA,"basicdez.dat") || die "Cannot open datfile: $!\n"; my @data; my $i = 0; while (<DATA>) { chomp; last if /^"EOS"$/; { @data = &quotewords('\s+', 0, $_); } # if all fields exist (gets rid of PER issue) if (($data[0]) && ($data[1]) && ($data[2])) { my @colors=split(/,/, $data[1]); print "Name = $data[0]\n"; for (@colors){ # print each color print "Color = $_\n"; } print "Date = $data[2]\n"; } }

    -phill

      Two small remarks:

      • for (@colors){ print "Color = $_\n"; }
        can lead to nasty surprises as you are overwriting $_ of the while loop. So either add local $_; before the loop or use a loop variable
        for my $color (@colors){ print "Color = $color\n"; }
      • if (($data[0]) && ($data[1]) && ($data[2])) {
        is quite restrictive. This doesn't allow for empty fields or lines without date. Alternatives would be if (@data == 3) or the next if suggestion by dragonchild. Of course, basicdez has to specify himself which of the alternatives fits his requirements.

      -- Hofmator

Re: Comma Delimitted Fields..
by Masem (Monsignor) on Oct 18, 2001 at 23:54 UTC
    You're close: what you need to do is now split the second data field $data[1] into several parts, preferably with the split function:
    # instead of print "Color =" above, .... foreach my $color ( split /,/ $data[1] ) { print "Color = $color\n"; }

    -----------------------------------------------------
    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
    "I can see my house from here!"
    It's not what you know, but knowing how to find it if you don't know that's important

Re: Comma Delimitted Fields..
by scain (Curate) on Oct 19, 2001 at 00:01 UTC
    I imiagine there is more that one way, but assuming PER is a record delimiter, you need to check if you have hit a delimiter and then start grabbing data. I would wonder though if all of your records look like this (ie, all on one line) why do you need a delimiter?

    Anyway, assuming you do need the delimiter:

    /usr/bin/perl-Tw use strict; use Text::ParseWords; open(DATA,"basicdez.dat") || die "Cannot open datfile: $!\n"; my @data; my $i = 0; my $new_record=0; while (<DATA>) { chomp; last if /^"EOS"$/; if (/^PER\s*$/) { $new_record=1; } elsif ($new_record) { @data = &quotewords('\s+', 0, $_); print "Name = $data[0]\n"; print "Color = $data[1]\n"; print "Date = $data[2]\n"; $new_record = 0; } }
Re: Comma Delimitted Fields..
by dragonchild (Archbishop) on Oct 19, 2001 at 00:01 UTC
    Others have already answered your Color question. I'll address your other, unspoken question. Add the following line after the last
    next if /^"PER"$/;
    That will skip the 'PER' line. :-)

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.