Is it possible to modify lines in a file in-place?
Is it possible to parse a file line by line, and edit a line in-place while going through the lines?
Solution 1:
Is it possible to parse a file line by line, and edit a line in-place while going through the lines?
It can be simulated using a backup file as stdlib's fileinput
module does.
Here's an example script that removes lines that do not satisfy some_condition
from files given on the command line or stdin
:
#!/usr/bin/env python
# grep_some_condition.py
import fileinput
for line in fileinput.input(inplace=True, backup='.bak'):
if some_condition(line):
print line, # this goes to the current file
Example:
$ python grep_some_condition.py first_file.txt second_file.txt
On completion first_file.txt
and second_file.txt
files will contain only lines that satisfy some_condition()
predicate.
Solution 2:
fileinput module has very ugly API, I find beautiful module for this task - in_place, example for Python 3:
import in_place
with in_place.InPlace('data.txt') as file:
for line in file:
line = line.replace('test', 'testZ')
file.write(line)
main difference from fileinput:
- Instead of hijacking sys.stdout, a new filehandle is returned for writing.
- The filehandle supports all of the standard I/O methods, not just readline().
Some useful notes from @rocksNwaves placed in comment
Solution 3:
No. You cannot safely write to a file you are also reading, as any changes you make to the file could overwrite content you have not read yet. To do it safely you'd have to read the file into a buffer, updating any lines as required, and then re-write the file.
If you're replacing byte-for-byte the content in the file (i.e. if the text you are replacing is the same length as the new string you are replacing it with), then you can get away with it, but it's a hornets nest, so I'd save yourself the hassle and just read the full file, replace content in memory (or via a temporary file), and write it out again.