【问题标题】:Replicating "tail -f" with Python用 Python 复制“tail -f”
【发布时间】:2016-01-22 18:26:12
【问题描述】:

根据David Beazley's talk on generators,以下代码应复制UNIX tail -f 命令:

import time
def follow(thefile):
    thefile.seek(0,2)
    while True:
        line = thefile.readline()
        if not line:
            time.sleep(0.1)
            continue
        yield line

f = open('followed.txt')
lines = follow(f)

for i in lines:
    print i

如果我在 shell 中运行它,它正在做“某事”,并且确实会锁定 IPython 笔记本,但它不会打印出 follow.txt 的内容。为什么会这样?

【问题讨论】:

  • 你的方法适合我。
  • 你是如何追加到followed.txt的?如果您使用文本编辑器将文本添加到followed.txt,上面的代码可能不起作用,因为文本编辑器可能不会附加到原始文件——它可能正在创建一个新文件,然后将followed.txt 重命名为它。 ..
  • 如果您 f = open('followed.txt', 'a') 并同时调用 f.write,或者(在 unix 上)使用 echo "some text" >> followed.txt 之类的东西附加,您发布的代码将起作用。
  • 我在 windows 7 中使用了你的代码,并用 notepad++ 编辑了文件,效果很好

标签: python generator yield tail seek


【解决方案1】:

我试过这个脚本,它可以工作。

您必须确保您的输入文件是一个正在增长的文件。如果不是,它会挂起并期待新的增长行。

这是一个脚本,每 5 秒将带有时间戳的行写入 sample.csv。

import os
import time
import datetime

while True:
    os.system("echo " + "sample line with timestamp:{0}".format(datetime.datetime.now()) + " >> " + " sample.csv")
    time.sleep(5)

使用您的tail -f 脚本阅读它,您将看到输出。

【讨论】:

  • 见我上面的评论。
  • @pyderman 您无法添加一行并保存文件。它将创建一个具有相同名称的新文件
  • 有道理;我想知道上面的 E 先生是如何用文本编辑器实现的。
  • @Pyderman 很高兴它有帮助。顺便说一句,幻灯片真的很棒,感谢您的分享!
  • @haifzhan 这并不总是正确的。这取决于编辑器以及它是否使用写时复制。
【解决方案2】:

follow() 生成器只会返回在调用follow() 之后 写入文件的行。 seek(0,2) 将光标放在文件的 end 处,然后尝试从该点开始读取新行。

tail 通常默认输出最后 10 行。如果你想要这样的东西

def follow(thefile):
    n_lines = 0
    # Seek to the end of the file
    thefile.seek(0,2)
    # Seek the cursor back one character at a time until you
    # reach the beginning of the file or 10 newlines are found.
    while n_lines < 10 and thefile.tell() > 0:
        # Go back one character and read it.
        thefile.seek(-1, 1)
        c = thefile.read(1)
        # Only go back 10 lines
        if c == '\n':
            n_lines += 1:
        # Reset the cursor position for the character we just read
        thefile.seek(-1, 1)

    while True:
        line = thefile.readline()
        if not line:
            time.sleep(0.1)
            continue
        yield line

【讨论】:

    猜你喜欢
    • 2015-08-03
    • 1970-01-01
    • 2018-02-04
    • 1970-01-01
    • 2023-04-05
    • 2017-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多