Get last n lines of a file, similar to tail

前端 未结 30 2329
挽巷
挽巷 2020-11-22 03:46

I\'m writing a log file viewer for a web application and for that I want to paginate through the lines of the log file. The items in the file are line based with the newest

相关标签:
30条回答
  • 2020-11-22 04:02
    import itertools
    fname = 'log.txt'
    offset = 5
    n = 10
    with open(fname) as f:
        n_last_lines = list(reversed([x for x in itertools.islice(f, None)][-(offset+1):-(offset+n+1):-1]))
    
    0 讨论(0)
  • 2020-11-22 04:04

    On second thought, this is probably just as fast as anything here.

    def tail( f, window=20 ):
        lines= ['']*window
        count= 0
        for l in f:
            lines[count%window]= l
            count += 1
        print lines[count%window:], lines[:count%window]
    

    It's a lot simpler. And it does seem to rip along at a good pace.

    0 讨论(0)
  • 2020-11-22 04:06

    For efficiency with very large files (common in logfile situations where you may want to use tail), you generally want to avoid reading the whole file (even if you do do it without reading the whole file into memory at once) However, you do need to somehow work out the offset in lines rather than characters. One possibility is reading backwards with seek() char by char, but this is very slow. Instead, its better to process in larger blocks.

    I've a utility function I wrote a while ago to read files backwards that can be used here.

    import os, itertools
    
    def rblocks(f, blocksize=4096):
        """Read file as series of blocks from end of file to start.
    
        The data itself is in normal order, only the order of the blocks is reversed.
        ie. "hello world" -> ["ld","wor", "lo ", "hel"]
        Note that the file must be opened in binary mode.
        """
        if 'b' not in f.mode.lower():
            raise Exception("File must be opened using binary mode.")
        size = os.stat(f.name).st_size
        fullblocks, lastblock = divmod(size, blocksize)
    
        # The first(end of file) block will be short, since this leaves 
        # the rest aligned on a blocksize boundary.  This may be more 
        # efficient than having the last (first in file) block be short
        f.seek(-lastblock,2)
        yield f.read(lastblock)
    
        for i in range(fullblocks-1,-1, -1):
            f.seek(i * blocksize)
            yield f.read(blocksize)
    
    def tail(f, nlines):
        buf = ''
        result = []
        for block in rblocks(f):
            buf = block + buf
            lines = buf.splitlines()
    
            # Return all lines except the first (since may be partial)
            if lines:
                result.extend(lines[1:]) # First line may not be complete
                if(len(result) >= nlines):
                    return result[-nlines:]
    
                buf = lines[0]
    
        return ([buf]+result)[-nlines:]
    
    
    f=open('file_to_tail.txt','rb')
    for line in tail(f, 20):
        print line
    

    [Edit] Added more specific version (avoids need to reverse twice)

    0 讨论(0)
  • 2020-11-22 04:06

    I had to read a specific value from the last line of a file, and stumbled upon this thread. Rather than reinventing the wheel in Python, I ended up with a tiny shell script, saved as /usr/local/bin/get_last_netp:

    #! /bin/bash
    tail -n1 /home/leif/projects/transfer/export.log | awk {'print $14'}
    

    And in the Python program:

    from subprocess import check_output
    
    last_netp = int(check_output("/usr/local/bin/get_last_netp"))
    
    0 讨论(0)
  • 2020-11-22 04:07

    Another Solution

    if your txt file looks like this: mouse snake cat lizard wolf dog

    you could reverse this file by simply using array indexing in python '''

    contents=[]
    def tail(contents,n):
        with open('file.txt') as file:
            for i in file.readlines():
                contents.append(i)
    
        for i in contents[:n:-1]:
            print(i)
    
    tail(contents,-5)
    

    result: dog wolf lizard cat

    0 讨论(0)
  • 2020-11-22 04:07
    abc = "2018-06-16 04:45:18.68"
    filename = "abc.txt"
    with open(filename) as myFile:
        for num, line in enumerate(myFile, 1):
            if abc in line:
                lastline = num
    print "last occurance of work at file is in "+str(lastline) 
    
    0 讨论(0)
提交回复
热议问题