I was working on some log processing the other day when I encountered a situation
where I wanted to have the python equivilant of Unix’s head and tail commands.
The problem here is that most anywhere you look, Python’s version of tail tends to share the same problems.
Reads the entire file into memory.
Iterate over the entire file.
Obviously, this can be quite problematic when you have 300mb logs constantly processing. Here is a more efficent version of tail:
importosdeftail(filename,count=1,offset=1024):""" A more efficent way of getting the last few lines of a file. Depending on the length of your lines, you will want to modify offset to get better performance. """f_size=os.stat(filename).st_sizeiff_size==0:return[]withopen(filename,'r')asf:iff_size<=offset:offset=int(f_size/2)whileTrue:seek_to=min(f_size-offset,0)f.seek(seek_to)lines=f.readlines()# Empty fileifseek_to<=0andlen(lines)==0:return[]# count is larger than lines in fileifseek_to==0andlen(lines)<count:returnlines# Standard caseiflen(lines)>=(count+1):returnlines[count*-1:]defhead(filename,count=1):""" This one is fairly trivial to implement but it is here for completeness. """withopen(filename,'r')asf:lines=[f.readline()forlineinxrange(1,count+1)]returnfilter(len,lines)