http://www.perlmonks.org?node_id=930426

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

Hi , when I try to open file with > for writing this file already exists but after it is opened the contents become blank can we open file in perl preserving its contents and for writing and also can the contents of such file opened for wrting be modified on the fly using search replace your help is much appreciates.. thanks ;
open (HAN , ">" ,'D:\RAM\perl\test') or die "$!"; while (<HAN>){ s/e/\*\*/ig; print HAN ; }

Replies are listed 'Best First'.
Re: opening file for editing
by exilepanda (Friar) on Oct 09, 2011 at 06:34 UTC
    > is open for write
    <HAN> is read a line from file
    This opening is not for read-write mode.
    consider a "+>" See: perldoc -f open
      using ">>" to append context into a file.
      well, why is the file going blank if i use > even though the file exists and has contents

        well, why is the file going blank if i use > even though the file exists and has contents

        Because that is what > means, see open

        ">" and ">>" are pipelines.

        For Perl and bash (one of the linux shells) ">" is the standard way to say: "redirect this stuff to the named file and overwrite (delete) its previous contents with this".

        And ">>" is the standard way to say: "add this material after the last line of the file (updating this contents) but preserve any previous contents that you found in this file". ">>" works also in perl and in bash

        If the file is missing both do basically the same. Create a "box" (the file) and dump all the "bricks" into this box.

        So, let's see what are you doing:

        open (HAN , ">" ,'D:\RAM\perl\test') or die "$!"; # DELETE the contents of this file and open it while (<HAN>){ s/e/\*\*/ig; # nothing here to mach, the file is empty, no survivor "e" chars print HAN ; # thus, nothing is changed and nothing left to print to the file }
Re: opening file for editing
by keszler (Priest) on Oct 09, 2011 at 06:35 UTC

    For a quick file update, perl -pi -e "s/e/\*\*/ig" D:\RAM\perl\test should work. If your needs are more complex, see open, in particular the '+<' and '+>' bits.

    update - changed single to double quotes around the s///ig after belatedly realizing the significance of D:

      I wont be able to do it using perl one liner what i want is open an already existing file search for a pattern replace it with something else on the fly i dont want any temp files to be created
        Just For Fun: ... to update a file "in place".
        ... open(my $READER,'+<',$Filename_S) or die "Can't open '$Filename_S'! $!"; open(my $WRITER,'+<',$Filename_S) # Don't use + '+>' or die "Can't open '$Filename_S'! $!"; # The overflow buffer: my @Buffer_a; while (<$READER>) { # Read (past tense) a line - buffer its replacement ... # Modify the line here! my $Update_s=... push(@Buffer_a,$Update_s); # Write from the overflow buffer if we can ... while (@Buffer_a && length($Buffer_a[0]) < tell($READER)-tell( +$WRITER)) { # Enough room to write $Buffer_a[0] so write it ... print $WRITER shift(@Buffer_a); }; }; # Nothing more to read ... close($READER) or die "Can't close '$Filename_S'! $!"; # If there's anything in the buffer write it ... while (@Buffer_a) { print $WRITER shift(@Buffer_a); }; # Truncate the file, in case, what we're writing is shorter than w +hat we read truncate($WRITER,tell($WRITER)); # ... and close close($WRITER) or die "Can't close '$Filename_S'! $!"; ...
        Be aware that if something should happen during the update one may be "up the creek without a paddle".

        you can do this in two steps:

        read open dump all to a variable (in memory) apply a substitution to this variable close re-open the file, now for writing print the changed variable to the file (overwrite the whole file) and close again

        No temp files here, and your file is updated as you want. Use perldoc for the details.

        Then you'll have to switch to Microsoft Word ™.