如何实现py -onic等价的tail -F?

pra*_*pra 25 python file tail

对于某些关键字的出现,观察不断增长的文件尾端的pythonic方法是什么?

在shell中我可能会说:

tail -f "$file" | grep "$string" | while read hit; do
    #stuff
done
Run Code Online (Sandbox Code Playgroud)

Joc*_*zel 24

嗯,最简单的方法是不断读取文件,检查新内容并测试命中.

import time

def watch(fn, words):
    fp = open(fn, 'r')
    while True:
        new = fp.readline()
        # Once all lines are read this just returns ''
        # until the file changes and a new line appears

        if new:
            for word in words:
                if word in new:
                    yield (word, new)
        else:
            time.sleep(0.5)

fn = 'test.py'
words = ['word']
for hit_word, hit_sentence in watch(fn, words):
    print "Found %r in line: %r" % (hit_word, hit_sentence)
Run Code Online (Sandbox Code Playgroud)

readline如果您知道您的数据将以行显示,则此解决方案有效.

如果数据是某种流,则需要一个缓冲区,大于word您要查找的最大值,并先填充它.它变得有点复杂......

  • 再看一下; open只被调用一次.重复调用readline. (11认同)

小智 5

def tail(f):
    f.seek(0, 2)

    while True:
        line = f.readline()

        if not line:
            time.sleep(0.1)
            continue

        yield line

def process_matches(matchtext):
    while True:
        line = (yield)  
        if matchtext in line:
            do_something_useful() # email alert, etc.


list_of_matches = ['ERROR', 'CRITICAL']
matches = [process_matches(string_match) for string_match in list_of_matches]    

for m in matches: # prime matches
    m.next()

while True:
    auditlog = tail( open(log_file_to_monitor) )
    for line in auditlog:
        for m in matches:
            m.send(line)
Run Code Online (Sandbox Code Playgroud)

我用它来监视日志文件.在完整实现中,我将list_of_matches保存在配置文件中,以便可以将其用于多种用途.在我的增强列表中,支持正则表达式而不是简单的"输入"匹配.