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

Hello, I have a text file for a data file. (memberpoints.txt) This is exatcly how the data file looks. ------file vegeta-44 matriz-22 evac-500 fritzilldo-200 teenreality-15 ------------ Now if I want to open the file, and find the string "vegeta-44" and then after its found I want to replace it with "vegeta-50" (adds 6 points to vegetas total points) What perl commands would I need to do this? and is this possible? Thank you, Anthony

Replies are listed 'Best First'.
Re: Editing files...please help
by Fastolfe (Vicar) on Jan 28, 2001 at 09:49 UTC
    Please wrap your code/format-sensitive text in <code> tags so that we can read it. For everyone else's benefit:
    ------file vegeta-44 matriz-22 evac-500 fritzilldo-200 teenreality-15 ------------
    Something simple like this might work for you:
    perl -pi.bak -e 's/(?<=vegeta-)(\d+)/$1 + 6/e' memberpoints.txt
    I might suggest that you put your data in a "real" data format, such as via dbmopen or tie a DB_File to a hash. Then your changes could be as simple as:
    $hash{vegeta} += 6;
    Likewise, a CSV file with DBD::CSV could be updated with a simple DBI 'update'.
Re: Editing files...please help
by Trimbach (Curate) on Jan 28, 2001 at 10:04 UTC
    Well, if your data file looks EXACTLY like you stated (that is, a file with only 5 lines) using a database (either the tied hash variety or something using DBI) is a little overkill.

    If you know about reading and writing Perl files, try reading in the whole file, changing the part you want to change, then writing the whole file back to update it. Like this:

    # Load in the whole file open (FILE, "memberpoints.txt") or die "Can't read: $!"; while (<FILE>) { chomp; ($name, $number) = split "-"; $field ($name) = $number; } # Change whatever you want $field{'vegeta'} += 6; # ..etc # Write the whole file back (replacing what was there before) open (FILE, ">memberpoints.txt") or die "Can't write: $!"; foreach (keys %field) { print FILE "$_-$field{$_}\n"; }
    But, keep in mind that although something like this works fine for tiny files it doesn't scale well, so if your file gets bigger later, or needs to be accessed lots and lots of times (multiple times per second) you should look into more flexible solutions like a tied hash (SDBM, NDBM, GDBM and siblings) or a full-bore database like MySQL or PostgreSQL.

    Gary Blackburn
    Trained Killer

    Edited: Forgot to chomp the newline. Bad newline. Bad. Added the chomp in.

      And here's a from the docs (perldoc db_file) hack to read-in your text and create a dbm:
      use strict ; use DB_File ; use vars qw( %h $k $v ) ; # hash, key value tie %h, "DB_File", "memberpoints", O_RDWR|O_CREAT, 0640, $DB_HASH or die "Cannot open file 'memberpoints': $!\n"; # Load in the whole file data file into the hash/dbm open (FILE, "memberpoints.txt") or die "Can't read: $!"; while (<FILE>) { next unless /-/; chomp; my ($name, $number) = split "-"; $h {$name} = $number; } # print the contents of the hash/dbm while (($k, $v) = each %h) { print "$k -> $v\n" } untie %h ;
      Note: you'll do this once, then you need to write your update code along the lines of:
      use strict ; use DB_File ; use vars qw( %h $k $v ) ; # hash, key value tie %h, "DB_File", "memberpoints", O_RDWR|O_CREAT, 0640, $DB_HASH or die "Cannot open file 'memberpoints': $!\n"; # update $h{vegeta} += 6; # print the contents of the db (debuggin) while (($k, $v) = each %h) { print "$k -> $v\n" } untie %h ;
      Very rough but its cold here and my fingers are getting too stiff to type.

      Update: Fruit? it really was cutnpaste ...

      a

Did you _try_ to solve it on your own?
by orkysoft (Friar) on Jan 29, 2001 at 07:32 UTC
    If you have programmed before (in another language) then you should know it's possible, and you might've well thought of reading the file and changing that what should be changed and writing it back.

    If you're new to programming, I suggest you go read some books and play around with Perl and the examples from the book. You can't expect to be able to make a program that a company will use if you have little programming experience - the resulting program will most probably be unreliable, and perhaps even insecure.

    There's all sorts of other things that come into play here: E.g. if it's a CGI program, it might be run multiple times simultaneously, and multiple instances might try to write to the same file before other instances are finished (race condition). You'll need to research 'file locking' (flock) if it's a CGI script.

    If it's a(n interactive) program meant to be run by only one user, you won't need file locking.