Insert string at the beginning of each line

Question:

How can I insert a string at the beginning of each line in a text file, I have the following code:

f = open('./ampo.txt', 'r+')
with open('./ampo.txt') as infile:
    for line in infile:
        f.insert(0, 'EDF ')
f.close

I get the following error:

'file' object has no attribute 'insert'
Asked By: philberndt

||

Answers:

You can’t modify a file inplace like that. Files do not support insertion. You have to read it all in and then write it all out again.

You can do this line by line if you wish. But in that case you need to write to a temporary file and then replace the original. So, for small enough files, it is just simpler to do it in one go like this:

with open('./ampo.txt', 'r') as f:
    lines = f.readlines()
lines = ['EDF '+line for line in lines]
with open('./ampo.txt', 'w') as f:
    f.writelines(lines)
Answered By: David Heffernan
f = open('./ampo.txt', 'r')
lines = map(lambda l : 'EDF ' + l, f.readlines())
f.close()
f = open('./ampo.txt', 'w')
map(lambda l : f.write(l), lines)
f.close()
Answered By: lollo

For a file not too big:

with open('./ampo.txt', 'rb+') as f:
    x = f.read()
    f.seek(0,0)
    f.writelines(('EDF ', x.replace('n','nEDF ')))
    f.truncate()

Note that , IN THEORY, in THIS case (the content is augmented), the f.truncate() may be not really necessary. Because the with statement is supposed to close the file correctly, that is to say, writing an EOF (end of file ) at the end before closing.
That’s what I observed on examples.
But I am prudent: I think it’s better to put this instruction anyway. For when the content diminishes, the with statement doesn’t write an EOF to close correctly the file less far than the preceding initial EOF, hence trailing initial characters remains in the file.
So if the with statement doens’t write EOF when the content diminishes, why would it write it when the content augments ?

For a big file, to avoid to put all the content of the file in RAM at once:

import os

def addsomething(filepath, ss):
    if filepath.rfind('.') > filepath.rfind(os.sep):
        a,_,c = filepath.rpartition('.')
        tempi = a + 'temp.' + c
    else:
        tempi = filepath + 'temp'

    with open(filepath, 'rb') as f, open(tempi,'wb') as g:
        g.writelines(ss + line for line in f)

    os.remove(filepath)
    os.rename(tempi,filepath)


addsomething('./ampo.txt','WZE')
Answered By: eyquem

Here’s a solution where you write to a temporary file and move it into place. You might prefer this version if the file you are rewriting is very large, since it avoids keeping the contents of the file in memory, as versions that involve .read() or .readlines() will. In addition, if there is any error in reading or writing, your original file will be safe:

from shutil import move
from tempfile import NamedTemporaryFile

filename = './ampo.txt'
tmp = NamedTemporaryFile(delete=False)
with open(filename) as finput:
    with open(tmp.name, 'w') as ftmp:
        for line in finput:
            ftmp.write('EDF '+line)
move(tmp.name, filename)
Answered By: Mark Longair

Python comes with batteries included:

import fileinput
import sys

for line in fileinput.input(['./ampo.txt'], inplace=True):
    sys.stdout.write('EDF {l}'.format(l=line))

Unlike the solutions already posted, this also preserves file permissions.

Answered By: unutbu
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.