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