如何实现与tail-F等价的pythonic?

2024-05-14 10:46:33 发布

您现在位置:Python中文网/ 问答频道 /正文

什么是Python式的方式来观察一个不断增长的文件的尾部出现某些关键字?

在shell中,我可以说:

tail -f "$file" | grep "$string" | while read hit; do
    #stuff
done

Tags: 文件readstring方式关键字shelldogrep
3条回答

您可以使用“选择”来轮询文件中的新内容。

def tail(filename, bufsize = 1024):
    fds = [ os.open(filename, os.O_RDONLY) ]
    while True:
        reads, _, _ = select.select(fds, [], [])
        if 0 < len(reads):
            yield os.read(reads[0], bufsize)
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)

我用它来监视日志文件。在完整的实现中,我在一个配置文件中保存了匹配项的列表,以便它可以用于多种目的。在我的增强列表中是对regex的支持,而不是简单的“in”匹配。

最简单的方法就是不断地从文件中读取,检查新的内容并测试点击率。

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)

如果您知道数据将以行的形式出现,那么使用readline的这个解决方案就可以工作。

如果数据是某种类型的流,您需要一个缓冲区,大于您要查找的最大的word,然后先填充它。这样会更复杂一点。。。

相关问题 更多 >

    热门问题