Search code examples
pythonfilereversetailhead

head, tail and backward read by lines of a text file


How to implement somethig like the 'head' and 'tail' commands in python and backward read by lines of a text file?


Solution

  • This is my personal file class ;-)

    class File(file):
        """ An helper class for file reading  """
    
        def __init__(self, *args, **kwargs):
            super(File, self).__init__(*args, **kwargs)
            self.BLOCKSIZE = 4096
    
        def head(self, lines_2find=1):
            self.seek(0)                            #Rewind file
            return [super(File, self).next() for x in xrange(lines_2find)]
    
        def tail(self, lines_2find=1):  
            self.seek(0, 2)                         #Go to end of file
            bytes_in_file = self.tell()
            lines_found, total_bytes_scanned = 0, 0
            while (lines_2find + 1 > lines_found and
                   bytes_in_file > total_bytes_scanned): 
                byte_block = min(
                    self.BLOCKSIZE,
                    bytes_in_file - total_bytes_scanned)
                self.seek( -(byte_block + total_bytes_scanned), 2)
                total_bytes_scanned += byte_block
                lines_found += self.read(self.BLOCKSIZE).count('\n')
            self.seek(-total_bytes_scanned, 2)
            line_list = list(self.readlines())
            return line_list[-lines_2find:]
    
        def backward(self):
            self.seek(0, 2)                         #Go to end of file
            blocksize = self.BLOCKSIZE
            last_row = ''
            while self.tell() != 0:
                try:
                    self.seek(-blocksize, 1)
                except IOError:
                    blocksize = self.tell()
                    self.seek(-blocksize, 1)
                block = self.read(blocksize)
                self.seek(-blocksize, 1)
                rows = block.split('\n')
                rows[-1] = rows[-1] + last_row
                while rows:
                    last_row = rows.pop(-1)
                    if rows and last_row:
                        yield last_row
            yield last_row
    

    Example usage:

    with File('file.name') as f:
        print f.head(5)
        print f.tail(5)
        for row in f.backward():
            print row