2

I'd like to modify some characters of a file in-place, without having to copy the entire content of the file in another, or overwrite the existing one. However, it doesn't seem possible to just replace a character by another:

>>> f = open("foo", "a+")  # file does not exist
>>> f.write("a")
1
>>> f.seek(0)
0
>>> f.write("b")
1
>>> f.seek(0)
0
>>> f.read()
'ab'

Here I'd have expected "a" to be replaced by "b", so that the content of the file would be just "b", but this is not the case. Is there a way to do this?

michaelmeyer
  • 7,985
  • 7
  • 30
  • 36

4 Answers4

3

That's because of the mode you're using, in append mode, the file pointer is moved to the end of file before write, you should open your file in w+ mode:

f = open("foo", "w+")  # file does not exist
f.write("samething")
f.seek(1)
f.write("o")
f.seek(0)
print f.read() # prints "something"

If you want to do that on an existing file without truncating it, you should open it in r+ mode for reading and writing.

Guillaume
  • 10,463
  • 1
  • 33
  • 47
1

Truncate the file using file.truncate first:

>>> f = open("foo", "a+") 
>>> f.write('a')
>>> f.truncate(0)  #truncates the file to 0 bytes
>>> f.write('b')
>>> f.seek(0)
>>> f.read()
'b'

Otherwise open the file in w+mode as suggested by @Guillaume.

Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
0
import fileinput

for line in fileinput.input('abc', inplace=True):
    line = line.replace('t', 'ed')
    print line,

This doesn't replace character by character, instead it scans through each line replacing required character and writes the modified line.

For example: file 'abc' contains:

i want 
to replace
character

After executing, output would be:

i waned
edo replace
characeder

Will it help you? Hope so..

rajpy
  • 2,436
  • 5
  • 29
  • 43
0

I believe that you may be able to modify the example from this answer.

https://stackoverflow.com/a/290494/1669208

import fileinput

for line in fileinput.input("test.txt", inplace=True):
    print line.replace(char1, char2),
Community
  • 1
  • 1
Dan Grahn
  • 9,044
  • 4
  • 37
  • 74