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

I'm trying to open a file in write mode, do a simple

$file =~ s/word1/word2/;

and close it. I'm new at perl.. any code examples? Also, when i look at a file after running this script, the file is blank. Isn't this script just opening and closing a file? -Lisa

#!/usr/bin/perl -w $file = "file.txt"; open(OUT, ">$file"); close (OUT); print "Content-type: text/html\n\n";

Replies are listed 'Best First'.
Re: simple substitution
by davido (Cardinal) on Jan 04, 2004 at 06:14 UTC
    Try this:

    my $file = "file.txt"; open IN, "<$file" or die; open OUT, ">$file.tmp" or die; while ( my $line = <IN> ) { $line =~ s/word1/word2/g; print OUT $line; } close IN; close OUT or die; rename "$file.tmp", $file;

    But be careful in a multi-user or multi-process environment, especially such as CGI programming though, because no file locking is done, and the tempfile's name might already be in use by another instance of the process. If you turn this into CGI be sure to lock your files. And don't obtain "$file" from the user.


    Dave

      that did the trick... thanx... wolfy.
Re: simple substitution
by tachyon (Chancellor) on Jan 04, 2004 at 07:15 UTC
    perl -pi.bak -e 's/this/that/g' file.txt

    cheers

    tachyon

      Or, equivalently,
      local $^I = '.bak'; while (<>) { s/this/that/g; print; }


      Who is Kayser Söze?
      Code is (almost) always untested.

        Challenge: find the quote -> 'too many notes (jweed), too many notes'

        cheers

        tachyon

Re: simple substitution
by exussum0 (Vicar) on Jan 04, 2004 at 06:11 UTC
    1. You open the file and you close it, never read nor write from it. You should try and read up on file handles and loops.

    Something ala..

    while(my $line = <INHANDLE>) { $line=~s/word1/word2/; print OUTHANDLE $line; }
    2. If you are processing one file and wishing to change it, i might advise opening one file to read from as your original, and a tempfile as your output. modifying the file you are reading from works /sometimes/. Anyway, read your file in, and write out your changes to a temp file created via File::Temp.

    When you are done closing your original and temp files, remove the original and rename the new to the old one.


    Play that funky music white boy..
Re: simple substitution
by BUU (Prior) on Jan 04, 2004 at 06:04 UTC
    Note: open OUT,">$file"; the > mode creates the file if it doesn't exist or truncates it if it does. This is why the file is blank.

    As to your stated problem, aside from doing odd things with >+ mode and seek, the easiest way would probably be to open the file in read mode (<,or no mode) read the file in to an array doing any alteration, then close the file and open it in write mode and write your array. This isn't very secure though, as if your script crashes right after it opens the file in write mode you just lost all your data. The general way around this is to write the modified file data to a seperate file and then just rename that new file to the filename of the old one.
Re: simple substitution
by pg (Canon) on Jan 04, 2004 at 06:26 UTC
    use Tie::File; use strict; use warnings; my @contents; tie @contents, "Tie::File", "somefile"; s/foo/bar/g foreach (@contents); untie @contents;

    Please check out Tie::File document.

Re: simple substitution
by Anonymous Monk on Jan 04, 2004 at 16:29 UTC
    I'm new at perl..
    Yeah, that's what you wrote on your homenode in April 2001... How many more years to come?