Here's another way, featuring flock. It finds the first "unused" number when adding a new user, so the gaps are kept to a minimum.

#!/usr/bin/perl -- -*-fundamental-*- use strict; use Fcntl qw(:flock); my $type = shift or die "Need a type!\n"; my $title = shift or die "Need a title or user!\n"; my $desc = shift || ""; my $flatfile = "members.txt"; ## Format of file: ID|Title|Description &AddUser if $type =~ /add/i; &DeleteUser if $type =~ /delete/i; die qq[Invalid type of "$type"!\n]; exit; sub AddUser() { ## Add a new user to the flat file ## Open the file in read/write mode: open(FF, "+< $flatfile") or die "Could not open $flatfile: $!\n"; ## Now we lock it so nobody else messes with it until we're done flock(FF, LOCK_EX) or die "Could not flock $flatfile: $!\n"; ## Now, we read through until we find a "free" number my $goodnumber=0; my $newnumber; my $slurp=""; while(<FF>) { $goodnumber++; ($newnumber) = split(/|/, $_, 2); if ($newnumber != $goodnumber) { ## We have just skipped a number - the perfect place ## to add a new user! ## Decrease goodnumber temporarily $goodnumber--; ## Save this spot, so we can go back to it quickly ## We need to subtract the line we just read in, ## because the new entry must go *before* it my $position = tell(FF) - length $_; ## Save the current line, since we have already read it: $slurp = $_; ## Now we slurp the rest of the file into memory: ## Setting $/ allows us to read the whole thing at once ## by setting the input record separator ($/) to ## nothing. See perlvar for more. { local $/; $slurp .= <FF>; } ## Now we rewind the file back to where we marked it: seek(FF,$position,0); ## This bails us out of the while loop last; } } ## Increment (needed in case no "holes" found before the end of the +file) $goodnumber++; ## Some systems need this to switch from read to write: seek(FF,0,1); ## Add the new entry: print FF "$goodnumber|$title|$desc\n"; ## Add all the entries after that: print FF $slurp; ## We should not need to truncate, as the size is always ## increasing when adding a user, but just for fun: truncate(FF, tell(FF)); ## Close and unlock close(FF); print "Added user $goodnumber to $flatfile.\n"; exit; } ## end of AddUser sub DeleteUser() { ## Delete a user from the flat file ## What number user do we want? my $baduser = $title; ## Sanity check: $baduser =~ /^\d+$/ or die "User to delete must be a number!\n"; ## Open the file in read/write mode: open(FF, "+< $flatfile") or die "Could not open $flatfile: $!\n"; ## Now we lock it so nobody else messes with it until we're done flock(FF, LOCK_EX) or die "Could not flock $flatfile: $!\n"; ## Now, we read through until we find the "bad" number my $newnumber; my $slurp=""; while(<FF>) { ($newnumber) = split(/|/, $_, 2); if ($newnumber == $baduser) { ## Save the spot right before this user, so we can ## go back to it quickly later: my $position = tell(FF) - length $_; ## Now we slurp the rest of the file into memory: ## Setting $/ allows us to read the whole thing at once ## by setting the input record separator ($/) to ## nothing. See perlvar for more. { local $/; $slurp = <FF>; } ## Now we rewind the file back to where we marked it: seek(FF,$position,0); ## This bails us out of the while loop last; } } ## Some systems need this to switch from read to write: seek(FF,0,1); ## Add all the entries after the bad one: print FF $slurp; ## We do need to truncate, as the file size has shrunk: truncate(FF, tell(FF)); ## Close and unlock close(FF); if ($slurp) { print "Deleted user $baduser from $flatfile.\n"; } else { print "User $baduser not found in $flatfile.\n"; } exit; } ## end of DeleteUser

In reply to Re: Storing Info in a text File by turnstep
in thread Storing Info in a text File by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.