Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

changing data

by DS (Acolyte)
on Aug 30, 2002 at 16:01 UTC ( [id://194152]=perlquestion: print w/replies, xml ) Need Help??

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

Hi guys , how can I change one line inside a file : I need to open a file and replace a line inside it
open FL , "+<file" or die""; while (<FL>) { s/oldline/newline/g; }
seems not to work .. thanks for help

Replies are listed 'Best First'.
Re: changing data
by Limbic~Region (Chancellor) on Aug 30, 2002 at 16:58 UTC
    There are a number of different ways of doing this. The biggest problem to overcome is that normally, you can not have a file open for both reading and writing. You have to read the file in, make modifications, write to a new file, and then copy back over the original. There is a better way!!! I would recommend you use Tie::File (or learn $^I) Go to Tie::File
    for (@array) { s/PERL/Perl/g;# Replace PERL with Perl everywhere in the file }
    Changes you make to the array are reflected in the file immediately!
Re: changing data
by krujos (Curate) on Aug 30, 2002 at 16:20 UTC
    You need to write the file back out. What you have (assuming your regexp is correct and all of that) just changes the file in memory, not on the disk. It is also important to note that the global option is unnecessary in your situation (if your replacing a whole line why would you need to repeat). You will also replace oldline with new line other places in the file. If you have duplicate lines and want to keep some this will get hard for you.
    That said here is a way to do this. You need to store all of the lines in memory (check out push for this), change the one you need and write it back to the file. Also you are just going to append to the file the way you have your code now. If that is your intention you have it correct, if not read the documentation on open You should also be closing the file, but you are probably doing that further down in your code.
Re: changing data
by bart (Canon) on Aug 30, 2002 at 19:36 UTC
    The easiest way IMO is to use the -i command like switch, provided this is all the script has to do, either on the command line
    perl -i.bak file
    script:
    while(<>) { s/oldline/newline/g; print; }
    or including the -p switch:
    s/oldline/newline
    where both the while loop and the print are implicit.

    Or, alternatively, do it in the shebang line:

    #! perl -i.bak -p s/oldline/newline/

      If this is really all you are doing though, you might consider putting it all on the command line.

      perl -i.bak -pe 's/pattern/replacement/'

      If, however, you have decided to save your script in a file rather than just using a -e switch, then you might prefer to use the $^I special variable over the -i switch:

      #!/usr/bin/perl $^I = ".bak"; while (<>) { s/pattern/replacement/; print; }

      That way you won't forget that you have to supply the -i and clobber a file the next time you use the script. It also allows you to make the script itself executable without losing functionality. Putting it on the shebang line does too but this approach is better in that it is more flexible. For instance, you might not want to clobber file.bak if it exists but instead write to file.bak.N (where N is a sequence number) instead. Setting $^I in the script enables you to these kind of things.

      -sauoq
      "My two cents aren't worth a dime.";
      

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (2)
As of 2024-04-25 06:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found