On Mar 31, 7:10 pm, Mark Wooding <[EMAIL PROTECTED]> wrote: > Paul Rubin <http> wrote: > > You could do it "in place" in all those systems afaik, either opening > > the file for both reading and writing, or using something like mmap. > > Basically you'd leave the file unchanged up to line N, then copy lines > > downward starting from line N+1. At the end you'd use ftrunc to > > shrink the file, getting rid of the duplicate last line. > > Making a new copy and renaming it when you're finished is probably both > easier (don't have to keep seeking about all the time) and more reliable > (doesn't leave your file corrupted if you crash half-way through). > > Is there a standard wossname which does this? > > from __future__ import with_statement > from contextlib import contextmanager > import os, sys, errno > > def fresh_file(base, mode = 'w'): > """ > Return a file name and open file handle for a fresh file in the same > directory as BASE. > """ > for seq in xrange(50): > try: > name = '%s.new.%d' % (base, seq) > fd = os.open(name, os.O_WRONLY | os.O_CREAT | os.O_EXCL) > f = os.fdopen(fd, mode) > return name, f > except OSError, err: > if err.errno == errno.EEXIST: > pass > else: > raise > raise IOError(errno.EEXIST, os.strerror(errno.EEXIST), base) > > @contextmanager > def safely_writing(filename, mode = 'w'): > """ > Context manager for updating files safely. > > It produces a file object. If the controlled suite completes successfully, > the file named by FILENAME is atomically replaced by the material written > to the file object; otherwise the file is left alone. > > Safe in the presence of multiple simultaneous writers, in the sense that > the resulting file is exactly the output of one of the writers (chosen > nondeterministically). > """ > f = None > newname = None > try: > newname, f = fresh_file(filename, mode) > yield f > f.close() > f = None > os.rename(newname, filename) > finally: > if f is not None: > f.close() > if newname is not None: > try: > os.unlink(newname) > except: > pass > > It seems like an obvious thing to want. > > (Extra messing about will be needed on Windows, which doesn't have > proper atomic-rename semantics. Playing with the transactional > filesystem stuff is left as an exercise to the interested student.) > > -- [mdw]
Why not use the fileinput modules functionality to iterate over a file in-place,printing just those lines you want? - Paddy. -- http://mail.python.org/mailman/listinfo/python-list