3

I am using the following code to upload a file on server using FTP after editing it:

import fileinput

file = open('example.php','rb+')

for line in fileinput.input('example.php'):
    if 'Original' in line :
        file.write( line.replace('Original', 'Replacement'))

file.close()    

There is one thing, instead of replacing the text in its original place, the code adds the replaced text at the end and the text in original place is unchanged.

Also, instead of just the replaced text, it prints out the whole line. Could anyone please tell me how to resolve these two errors?

SanJeet Singh
  • 1,291
  • 2
  • 15
  • 28

3 Answers3

5

1) The code adds the replaced text at the end and the text in original place is unchanged.

You can't replace in the body of the file because you're opening it with the + signal. This way it'll append to the end of the file.

file = open('example.php','rb+')

But this only works if you want to append to the end of the document.

To bypass this you may use seek() to navigate to the specific line and replace it. Or create 2 files: an input_file and an output_file.


2) Also, instead of just the replaced text, it prints out the whole line.

It's because you're using:

file.write( line.replace('Original', 'Replacement'))

Free Code:

I've segregated into 2 files, an inputfile and an outputfile.

First it'll open the ifile and save all lines in a list called lines.

Second, it'll read all these lines, and if 'Original' is present, it'll replace it.

After replacement, it'll save into ofile.

ifile = 'example.php'
ofile = 'example_edited.php'

with open(ifile, 'rb') as f:
    lines = f.readlines()

with open(ofile, 'wb') as g:
    for line in lines:
        if 'Original' in line:
            g.write(line.replace('Original', 'Replacement'))

Then if you want to, you may os.remove() the non-edited file with:


More Info: Tutorials Point: Python Files I/O

Community
  • 1
  • 1
dot.Py
  • 5,007
  • 5
  • 31
  • 52
  • Thanks for the answer dot.Py but is there any way to do it without creating two files? – SanJeet Singh Jul 26 '16 at 16:56
  • 2
    @SanJeetSingh use ifile in both cases. First it will read in the lines, then it will open example.php output, clearing it and then you write the lines back in, leaving you with an edited file but the possibility of a trashed file if anything goes wrong. – Rolf of Saxony Jul 26 '16 at 17:05
0

The second error is how the replace() method works.

It returns the entire input string, with only the specified substring replaced. See example here.

To write to a specific place in the file, you should seek() to the right position first.

I think this issue has been asked before in several places, I would do a quick search of StackOverflow.

Maybe this would help?

Community
  • 1
  • 1
Noam
  • 550
  • 2
  • 11
-1

Replacing stuff in a file only works well if original and replacement have the same size (in bytes) then you can do

with open('example.php','rb+') as f:
    pos=f.tell()
    line=f.readline()
    if b'Original' in line:
        f.seek(pos)
        f.write(line.replace(b'Original',b'Replacement'))

(In this case b'Original' and b'Replacement' do not have the same size so your file will look funny after this)

Edit:

If original and replacement are not the same size, there are different possibilities like adding bytes to fill the hole or moving everything after the line.

janbrohl
  • 2,626
  • 1
  • 17
  • 15
  • `Replacing stuff in a file only works if original and replacement have the same size (in bytes)`. Can you post a source to this info? – dot.Py Jul 26 '16 at 16:53
  • I've just tried `s = 'abc'; t = s.replace('a', 'aaa'); print t` and it works fine. – dot.Py Jul 26 '16 at 16:55
  • For strings adding/removing parts is no problem as a new one is created anyway but if you want to add or remove some bytes in a file you have to move everything after it - which means reading and writing back of large parts. – janbrohl Jul 26 '16 at 17:19