mikael-g has asked for the wisdom of the Perl Monks concerning the following question:

Hi ! I have headache ..to take care of this file...to to remove one record at a time
10.00|val_time|email01@tech.com|email01 10.20|val_time|email02@cmv.com|email02 10.40|val_time|email03@air.com|email03 11.00|val_time|email04@drama.com|email04 11.20|val_time|email05@living.com|email05 11.40|val_time|email06@testrr.com|email06 12.00|val_time|email07@ball.com|email07 12.20|val_time|email08@lok.com|email08 12.40|val_time|email09@lome.com|email09 13.00|val_time|email10@faarik.com|email10
I have at flat dtabase file as shown above , each time , i try to delete one record from the file i am erasing the whole file , or getting errors

Is there someone who want to show me a simple method with file locking to remove the record which starts with --10.20 ..or any other bu using the first entry ??

the fields in the above file is (if you need it)
$id2|$status|$fromemail|$eform

thank you !

edited: Fri Jun 13 15:17:58 2003 by jeffa - bogotified email addresses, removed unecessary br tags

Replies are listed 'Best First'.
Re: Deleting a record from a flat text file
by jdporter (Paladin) on Jun 13, 2003 at 15:07 UTC
    The Tie::File module will do exactly what you want. The only thing that I would draw your special attention to is the flock method, which you'll need to call in order lock the file.
    my @a; my $o = tie @a, "Tie::File", $filename; $o->flock; # find and delete the first record with the given key val for my $i ( 0 .. $#a ) { my( $id2, $status, $fromemail, $eform ) = split /\|/, $a[$i]; if ( $id2 eq $id_to_remove ) { splice @a, $i, 1; last; } }

    jdporter
    The 6th Rule of Perl Club is -- There is no Rule #6.

Re: Deleting a record from a flat text file
by Ovid (Cardinal) on Jun 13, 2003 at 14:40 UTC

    Perhaps if you can show us the full code that deletes the file, that would help. Sometimes monks will give you a whole program for nothing, sometimes they won't. Typically, some up front work is encouraged.

    As for solving your problem there are several ways to go about it. How large is the typical file? How large is it likely to get? You can simply write the good records to a new file and rename it to the old one (which would take less memory if you have a big file), or you could read the entire file, only sticking good records into an array and then write that array back out to the file after you have truncated it at the beginning. However, these and other strategies can be dependent upon your requirements.

    Cheers,
    Ovid

    New address of my CGI Course.
    Silence is Evil (feel free to copy and distribute widely - note copyright text)

      the code is as follows .... i have a problem to build the the second part with the first, to write back ,...
      #!/usr/bin/perl # e_id="10.20"; # # open (DATABASE, "mybase.txt"); while (<DATABASE>) { $row = $_; chop $row; ($id2, $status, $fromemail, $efrom,) = split(/\|/, $row); if ($form{'e_id'} ne $id2) {$new_row .= "$row\n";} } close (DATABASE); #writing the '$new_row' to the textfield:<p> open (DATABASE, ">mybase.txt"); print DATABASE "$new_row"; close (DATABASE);

      edited: Sat Jun 14 14:05:07 2003 by jeffa - code tags

        You have commented out the first call to open which means the mybase.txt is not being read. Then you clobber the file with your second open.

        Couple of things I'd point out. Always, always, always, check the return value of open, you'll save yourself a lot of grief:

        open(DATABASE, "mybase.txt") || die "open mybase.txt - $!\n";
        Try not to use chop to remove newlines, use chomp instead. chop will remove (and return) the last character in the string regardless of whether it's a newline or not.

        -- vek --
        A few things you might want to consider.

        If you're going to be using this script often you might want to use a command line argument for your pattern matching, and you might want to save a copy of the file you're editing to avoid any unpleasant errors (like deleting the whole file). Just a thought.

        -muoyo