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

I have a preferences file formatted:
pref1\t0\n pref2\t1\n pref3\t0\n pref4\t1\n

What code would I use to search for the line starting with $a (pref1, pref2... etc) and change the single digit following it to another single digit. I do not want to have to rewrite the entire file because it may be quite long.

thanks
z

Replies are listed 'Best First'.
Re: How can I replace a single character (digit) in a file
by kschwab (Vicar) on Jul 30, 2001 at 01:17 UTC
    Here's one way to do it, supposing you wanted to change the number after "pref3" from 0 to 9:
    open(PREF,"+< preffile") or die; while (<PREF>) { # if we see pref3 set to 0 if (/^pref3\t0$/) { # you need to rewind two chars to get # before the 0 and the newline , which # you've already gone past seek(PREF,-2,1) or die; # print a "9" in this spot print PREF "9"; # move forward one char past the newline # to continue reading. seek(PREF,1,1) or die; } } close PREF;
    See open for the <+ read-write mode, and seek for the seek() bit.

    Update: I should note that this only works when the replacement string is the same length as the original. See "perldoc -q 'how do I change one line'" for a complete answer.

    Update2:Replaced the read() with while(<PREF>), since it's not likely that all the lines in the file are 8 chars long.

      Thanks for your guidance, the seek command worked like a charm. Here's what I ended up using:
      open THIS_FILE, "+<$listOption" or die "ERROR: SearchFile: $!"; while (<THIS_FILE>) { if (/^$genre\t\d$/) { seek(THIS_FILE, -2, 1) or die; print THIS_FILE $option; seek(THIS_FILE, 1, 1) or die; } } close THIS_FILE;
      Pretty close to what you updated to. It took me a while to realize I shouldn't be using the 8 char read.

      Thanx
      -Zach (SFSC)

      This is a much better solution than mine. :)

      -----------------------------------
      Frank Wiles <frank@wiles.org>
      http://frank.wiles.org

Re: How can I replace a single character (digit) in a file
by ides (Deacon) on Jul 30, 2001 at 01:17 UTC
    I'm not 100% clear on your question, so I'm assuming you
    have a line with:

    pref1\t0\n

    and you want to be able to change it to:

    pref1\t1\n

    without rewriting the entire file? If that is correct you can do this which is basically straight out of the Perl Cookbook. Note it uses quite a bit of memory if the file is going to be large.

    my $pref = 'pref1'; open(FH, "+< $FILE") or die "Error opening $FILE: $!\n" my @lines = <FH>; seek(FH,0,0); my $count = 0; foreach my $l ( @lines ) { $count++; # Skip lines not matching $pref if( $line !~ /^$pref/ ) { next; } my ($pref, $num) =~ /^(.*?)\t(.*?)$/; $num = 1; $lines[$count] = "$pref\t$num\n"; } print FH @lines; truncate(FH, tell(FH)); close(FH);
    -----------------
    Frank Wiles <frank@wiles.org>
    http://frank.wiles.org

    Edit kudra, 2001-07-30 Changed pre tags to code tags