Python tête, queue et en arrière lire par les lignes d'un fichier texte

comment mettre en œuvre somethig comme les commandes 'head' et 'tail' en python et en arrière lu par des lignes d'un fichier texte?

8
demandé sur user739650 2011-05-05 14:17:27

3 réponses

C'est mon fichier de classe ;-)

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

exemple d'usage:

with File('file.name') as f:
    print f.head(5)
    print f.tail(5)
    for row in f.backward():
        print row
21
répondu fdb 2011-05-05 10:27:24

head est facile:

from itertools import islice
with open("file") as f:
    for line in islice(f, n):
        print line

tail est plus difficile si vous ne voulez pas garder tout le fichier en mémoire. Si l'entrée est un fichier, vous pouvez commencer à lire les blocs de début à la fin du fichier. L'original tail fonctionne aussi si l'entrée est un tuyau, donc une solution plus générale est de lire et de rejeter l'entrée entière, sauf pour les dernières lignes. Une façon facile de le faire est collections.deque :

from collections import deque
with open("file") as f:
    for line in deque(f, maxlen=n):
        print line

dans les deux ces extraits de code, n est le nombre de lignes à imprimer.

4
répondu Sven Marnach 2011-05-05 10:34:53

queue:

def tail(fname, lines):
    """Read last N lines from file fname."""
    f = open(fname, 'r')
    BUFSIZ = 1024
    f.seek(0, os.SEEK_END)
    fsize = f.tell()
    block = -1
    data = ""
    exit = False
    while not exit:
        step = (block * BUFSIZ)
        if abs(step) >= fsize:
            f.seek(0)
            exit = True
        else:
            f.seek(step, os.SEEK_END)
        data = f.read().strip()
        if data.count('\n') >= lines:
            break
        else:
            block -= 1
    return data.splitlines()[-lines:]
0
répondu Giampaolo Rodolà 2012-03-19 17:25:18