11

The last line of my file is:

29-dez,40,

How can I modify that line so that it reads:

29-Dez,40,90,100,50

Note: I don't want to write a new line. I want to take the same line and put new values after 29-Dez,40,

I'm new at python. I'm having a lot of trouble manipulating files and for me every example I look at seems difficult.

Harley Holcombe
  • 175,848
  • 15
  • 70
  • 63
UcanDoIt
  • 1,775
  • 7
  • 20
  • 27
  • It's hard because it's hard. What you're doing is not really sensible for text files with variable-length lines. – S.Lott Nov 29 '08 at 21:28
  • See http://stackoverflow.com/questions/328059/create-a-list-that-contain-each-line-of-a-file for what looks like the follow-up to this question. – S.Lott Nov 29 '08 at 22:52
  • I modified your question fairly significantly, let me know if I've misunderstood something. S. Lott is right too, although it seems like it should be simple, modifying a file is actually quite difficult. – Harley Holcombe Dec 01 '08 at 00:36

4 Answers4

7

Unless the file is huge, you'll probably find it easier to read the entire file into a data structure (which might just be a list of lines), and then modify the data structure in memory, and finally write it back to the file.

On the other hand maybe your file is really huge - multiple GBs at least. In which case: the last line is probably terminated with a new line character, if you seek to that position you can overwrite it with the new text at the end of the last line.

So perhaps:

f = open("foo.file", "wb")
f.seek(-len(os.linesep), os.SEEK_END) 
f.write("new text at end of last line" + os.linesep)
f.close() 

(Modulo line endings on different platforms)

jfs
  • 399,953
  • 195
  • 994
  • 1,670
Douglas Leeder
  • 52,368
  • 9
  • 94
  • 137
  • 2
    For Python 3.2 and up, you can do the seek operation only from the beginning of a file(text file). – derek Jan 12 '16 at 17:39
  • 2022 update: `seek(0, 2)` will seek to the end of a file. See [docs](https://docs.python.org/3/tutorial/inputoutput.html#methods-of-file-objects) for caveats. – ddejohn Nov 23 '22 at 05:28
6

To expand on what Doug said, in order to read the file contents into a data structure you can use the readlines() method of the file object.

The below code sample reads the file into a list of "lines", edits the last line, then writes it back out to the file:

#!/usr/bin/python

MYFILE="file.txt"

# read the file into a list of lines
lines = open(MYFILE, 'r').readlines()

# now edit the last line of the list of lines
new_last_line = (lines[-1].rstrip() + ",90,100,50")
lines[-1] = new_last_line

# now write the modified list back out to the file
open(MYFILE, 'w').writelines(lines)

If the file is very large then this approach will not work well, because this reads all the file lines into memory each time and writes them back out to the file, which is very inefficient. For a small file however this will work fine.

Community
  • 1
  • 1
Jay
  • 41,768
  • 14
  • 66
  • 83
0

Don't work with files directly, make a data structure that fits your needs in form of a class and make read from/write to file methods.

Toni Ruža
  • 7,462
  • 2
  • 28
  • 31
0

I recently wrote a script to do something very similar to this. It would traverse a project, find all module dependencies and add any missing import statements. I won't clutter this post up with the entire script, but I'll show how I went about modifying my files.

import os
from mmap import mmap

def insert_import(filename, text):
    if len(text) < 1:
        return
    f = open(filename, 'r+')
    m = mmap(f.fileno(), os.path.getsize(filename))
    origSize = m.size()
    m.resize(origSize + len(text))
    pos = 0
    while True:
        l = m.readline()
        if l.startswith(('import', 'from')):
            continue
        else:
            pos = m.tell() - len(l)
            break
    m[pos+len(text):] = m[pos:origSize]
    m[pos:pos+len(text)] = text
    m.close()
    f.close()

Summary: This snippet takes a filename and a blob of text to insert. It finds the last import statement already present, and sticks the text in at that location.

The part I suggest paying most attention to is the use of mmap. It lets you work with files in the same manner you may work with a string. Very handy.