Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

updating a file

by Anonymous Monk
on Nov 28, 2001 at 23:47 UTC ( #128154=perlquestion: print w/replies, xml ) Need Help??

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

Hi,
I am a newcomer to perl, and writing a perl script to bascically open a file and update a few lines in it. For some reason the following code doesn't work for me
open (FILEHANDLE, "+<$dir/$header_file") or die "Couldn't open $dir/$h +eader_file \n"; while (<FILEHANDLE>) { $_ =~ s|solver_version_major_h.*|solver_version_major_h= $nums[0],|; $_ =~ s|solver_version_minor_h.*|solver_version_minor_h= $nums[1],|; $_ =~ s|solver_version_fix_h.*|solver_version_fix_h= $nums[2],|; print FILEHANDLE "$_"; } close FILEHANDLE;


please let me know what I am doing wrong here. It doesn't update the file for some reason, if i just do "print $_" in the loop it prints the right output to the stdout, which means its doing the substitution rigt, but doesnt write out to the file.

Replies are listed 'Best First'.
Use $^I (was Re: updating a file)
by chip (Curate) on Nov 29, 2001 at 01:49 UTC
    Little-known fact: the "-i" flag just sets the $^I variable. You can set it yourself. Then setting @ARGV, reading <>, and printing the result is all you have to do. Thus:

    local $^I = '.bak'; local @ARGV = ("$dir/$header_file"); while (<>) { s/foo/bar/; # whatever you want print; }

    Presto, magico, all done!

        -- Chip Salzenberg, Free-Floating Agent of Chaos

      nice work. impressed. I knew there would be an easier solution. Thanks. :-)
Re: updating a file
by IlyaM (Parson) on Nov 29, 2001 at 00:03 UTC
    Reading and writting at same time is not supported. At least you cannot read it line by line and modify these lines because variable length of record. Also I don't remember exact place in the docs but if you switch from reading to writing or backwards you must reset current position with seek.

    It is much more easier just make copy of this file (with File::Copy of course), open it for reading and open original file for writting.

Re: updating a file
by broquaint (Abbot) on Nov 29, 2001 at 00:20 UTC
    While you've got the right idea by open()ing the file in read/write mode, it doesn't work quite as one would hope. You may want to try using the inplace command line switch like so
    perl -pi -e 's/search_re/replace_re/g' $your_files_here
    For more info on those lovely little switches check out the manual. Also you may want to be a little (see. A LOT) cautious of the infamous dot-star (i.e .*). You can learn of it's dodgy dealings from Ovid here.
    HTH

    broquaint

Re: updating a file
by IraTarball (Monk) on Nov 29, 2001 at 00:21 UTC
    This code 'works' for me, well, for some strange distorted definition of 'works.' I think the problem here is that you are trying to update the current like, but you've just read the current line so the write happens on the next line. What I get when I run this is a horribly garbled header file.
    You could do this in a number of ways. The most straight forward would be to open one file for reading, one file for writing, and itterate through the read file, replacing the desired lines as you go.
    use File::Copy; open(RFH, "<ReadFile.h") or die "Trying:$!"; open(WFH, ">WriteFile.h") or die "Trying:$!"; while(<RFH>) { s/search/replace/; print WFH; } close RFH; close WFH; move ("WriteFile.h", "ReadFile.h") or die "With a vengance:$!";
    I didn't actually run this, but it should be close. You might want more descriptive diemessages.

    The idiomatic way to do this would be with an 'in place edit' that does the file move for you.

    $^I = '.old'; @ARGV = ("header.h"); while (<>) { s/search/replace/; print; }
    This will save the old file as "header.h.old" for you.
    (I did run this code) BTW: The $^I is equivalent to the '-i' switch mentioned above by broquaint

    Ira,

    "So... What do all these little arrows mean?"
    ~unknown

Re: updating a file
by Fastolfe (Vicar) on Nov 29, 2001 at 09:39 UTC
    For the record, this is a FAQ.
    $ perldoc -q 'change one line in a file' Found in /usr/lib/perl5/5.6.1/pod/perlfaq5.pod How do I change one line in a file/delete a line in a file/insert a line in the middle of a file/append to the beginning of a file?
    In addition to classics like Learning Perl and The Perl Cookbook, I also like to recommend sitting down one evening and reading through all of the perlfaqs. Even seasoned Perl coders tend to learn new things.
Re: updating a file
by Beatnik (Parson) on Nov 29, 2001 at 16:30 UTC
    perlopentut has several open() tips & tricks.

    Greetz
    Beatnik
    ... Quidquid perl dictum sit, altum viditur.
Re: updating a file
by Anonymous Monk on Nov 29, 2001 at 13:54 UTC
    hi. I have same problem..but I solved it with two different way . if you problem remain. contact me with: nsaberi@iraninfocenter.net for send my source. bye

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://128154]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (8)
As of 2021-05-07 14:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Perl 7 will be out ...





    Results (92 votes). Check out past polls.

    Notices?