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

Could anyone tell me what in this script separates the
records by a newline character? I am wanting to change
this to separate the entries/records with my own character, and not "\n". This script modifies records found in a flat-file database THANKS
#!/usr/local/bin/perl-w use strict; use CGI; my $query =new CGI; my $guest_file = "new_guestbook.html"; &print_page_start; if ($query->param()) { if ($query->param('new_name')) { if (&valid_form) { eval { open (GUESTS, "+>> $guest_file") or die "Can't open $guest_file: $!"; flock GUESTS, 2; seek GUESTS, 0, 0; my @guests = <GUESTS>; my @new_guests = (); foreach $guest (@guests) { chomp $guest; ($name, $email, $comments) = split /::/, $guest; if ($name eq $query->param('name') && $email eq $query->param('email') && $comments eq $query->param('comments')) { $name = $query->param('new_name'); $email = $query->param('new_email'); $comments = $query->param('new_comments'); $guest = "$name::$email::$comments"; } $guest .= "\n"; push @new_guests, $guest; } seek GUESTS, 0,0; truncate GUESTS, 0; print GUESTS @new_guests; close GUESTS; print "<P>Record(s) modified.</P>\n"; print "<A HREF=\"retrieve.pl\">Retrieve records.</A>\n"; } } else { &print_form; } } else { &print_form; } } else { &print_record_list; } chomp $@; if ($@) { print "ERROR: $@<BR>\n"; } &print_page_end; sub print_page_start { print $query->header; print "<HTML>\n<HEAD>\n<TITLE>Modify Records</TITLE>\n"; print "</HEAD>\n<BODY>\n"; print "<H1>Modify Records</H1>\n"; } sub print_form { print "<P>\n<FORM>\n"; if (!$query->param()) { print "Name: <INPUT TYPE=\"text\" NAME=\"new_name\"><BR>\n"; print "Email: <INPUT TYPE=\"text\" NAME=\"new_email\"><BR>\n"; print "Comments: <INPUT TYPE=\"text\" NAME=\"new_comments\"><BR> +\n"; print "VALUE=\"$comments\">$comments<BR>\n"; } else { if ($query->param('new_name')) { print "Name: <INPUT TYPE=\"text\" NAME=\"new_name\" "; print "VALUE=\"", $query->param('new_name'), "\"><BR>\n"; print "Email: <INPUT TYPE=\"text\" NAME=\"new_email\" "; print "VALUE=\"", $query->param('new_email'), "\"><BR>\n"; print "Comments: <INPUT TYPE=\"text\" NAME=\"new_comments\" + "; print "VALUE=\"", $query->param('new_comments'), "\"><BR>\n +"; } else { print "Name: <INPUT TYPE=\"text\" NAME=\"new_name\" "; print "VALUE=\"", $query->param('name'), "\"><BR>\n"; print "Email: <INPUT TYPE=\"text\" NAME=\"new_email\" "; print "VALUE=\"", $query->param('email'), "\"><BR>\n"; print "Comments: <INPUT TYPE=\"text\" NAME=\"new_comments\" + "; print "VALUE=\"", $query->param('comments'), "\"><BR>\n"; } } } print "<INPUT TYPE=\"hidden\" NAME=\"name\" "; print "VALUE=\"" . $query->param('name') . "\">\n"; print "<INPUT TYPE=\"hidden\" NAME=\"email\" "; print "VALUE=\"" . $query->param('email') . "\">\n"; print "<INPUT TYPE=\"hidden\" NAME=\"comments\" "; print "VALUE=\"" . $query->param('comments') . "\">\n"; print "</FORM>\n</P>\n"; sub valid_form { $return_code = 1; if (!$query->param('new_name')) { print "You must enter a name.<BR>\n"; $return_code = 0; } if (!$query->param('new_email')) { print "You must enter an email address.<BR>\n"; $return_code = 0; } if (!$query->param('comments')) { print "You must enter some comments.<BR>\n"; $return_code =0; } return $return_code; sub print_record_list { open (GUESTS, "< $guest_file") or die "Can't open guest file: $!"; while (<GUESTS>) { chomp; ($name, $email, $comments) = split /::/; print "<P>\n"; print "<FORM>\n"; print "Name: $name<BR>\n"; print "Email: $email<BR>\n"; print "Comments: $comments<BR>\n"; print "<INPUT TYPE=\"hidden\" NAME=\"name\" VALUE=\"$name\">\n"; print "<INPUT TYPE=\"hidden\" NAME=\"email\" VALUE=\"$email\">\n +"; print "<INPUT TYPE=\"hidden\" NAME=\"comments\" VALUE=\"$comment +s\">\n"; print "<INPUT TYPE=\"submit\" VALUE=\"Edit this entry\">\n"; print "</FORM>\n"; print "</P>\n"; } } sub print_page_end { print "</BODY>\n</HTML>\n"; } }

Replies are listed 'Best First'.
Re: changing DB delimiters
by azatoth (Curate) on Jun 20, 2001 at 10:28 UTC
Re: changing DB delimiters
by jeroenes (Priest) on Jun 20, 2001 at 11:19 UTC
    You can choose them yourself. See perlvar.

    local $/ = "vroom"; #$/ is input separator. From now on, # script will split lines on 'vroom' local $, = "PM!PM!" #$, is print rec separator. From now on, # script will print 'PM!PM!' between items of arr +ay
    Jeroen
    "We are not alone"(FZ)
      Actually, $, would be the field separator, while $\ is the record separator. If you want it to work for the given code, you'd need to do:
      local $/ = local $\ = local $, = "\n";
      or else the last record isn't properly terminated.

      -- Abigail

        Well, it depends on what you do, actually. I understand that he prints his 'DB' with print @guests. In that case, you need to separate the fields with $,. The $\ is active after each print statement, as appears from:
        $OUTPUT_FIELD_SEPARATOR
        $OFS
        $,
        The output field separator for the print operator. Ordinarily the print operator simply prints out its arguments without further adornment. To get behavior more like awk, set this variable as you would set awk's OFS variable to specify what is printed between fields. (Mnemonic: what is printed when there is a "," in your print statement.)

        $OUTPUT_RECORD_SEPARATOR
        $ORS
        $\
        The output record separator for the print operator. Ordinarily the print operator simply prints out its arguments as is, with no trailing newline or other end-of-record string added. To get behavior more like awk, set this variable as you would set awk's ORS variable to specify what is printed at the end of the print. (Mnemonic: you set `$\' instead of adding "\n" at the end of the print. Also, it's just like `$/', but it's what you get "back" from Perl.)
        So it makes no sense to set $, and $\ to the same value.

        Jeroen

Re: changing DB delimiters
by Abigail (Deacon) on Jun 20, 2001 at 20:31 UTC
    It looks quite obvious to me what makes the record separator. You are writing records called $guest to a file, and you append newlines to $guest just before storing it. Where else would you expect this to happen?

    Now that you have posted all this code (of which most is completely pointless - if you have a question about your database, don't post dozens of lines of HTML generation, it makes it much harder to figure out what's going on), why are you opening the file new_guestbook.html for append if you truncate it to 0 bytes before prints? And why aren't you checking the return value of flock? What if the flock fails?

    You should also realize that reading in the entire database and writing it out again is ineffecient. Why not just use a dbm file?

    -- Abigail

Re: changing DB delimiters
by thabenksta (Pilgrim) on Jun 21, 2001 at 18:28 UTC

    The Database is separated on the \n when you say my @guests = <GUESTS>;. When you assign a filehandle to an array, it automatically splits on \n. I'm not sure how to change this, but I assume that jeroenes is right. But I do know you can use split.

    my @guests = split(/delimiter/, <GUESTS>);

    hope that helps

    -thabenksta
    my $name = 'Ben Kittrell'; $name=~s/^(.+)\s(.).+$/\L$1$2/g; my $nick = 'tha' . $name . 'sta';
      Thank you so much Thabenksta, you and jeroenes are the ones that addressed the problem most effectively. I agree with you in that I'm wanting to write code to get around this kind of "default" setting of splitting records on the newline character.......although I'm still testing code to accomplish this.