2016-01-22 68 views
3

David Beazley's talk on generators,下面的代碼應該複製的UNIX tail -f命令:複製「尾-f」與Python

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筆記本,但不打印followed.txt的內容。爲什麼這樣?

+0

**澄清**:在代碼運行時,我用Vim打開followed.txt,添加一行任意文本並保存。仍然沒有打印。 – Pyderman

+1

您的方法適用於我。 –

+1

你如何追加'followed.txt'?如果使用文本編輯器將文本添加到'followed.txt',上面的代碼可能不起作用,因爲文本編輯器可能不會追加到原始文件 - 它可能正在創建一個新文件,然後重命名'followed.txt '對它... – unutbu

回答

4

我試過腳本,它的工作原理。

你必須確保你的輸入文件是增長的文件。如果不是它掛着並期待新的成長線。

下面是一個腳本,每隔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腳本來閱讀它,您將看到輸出。

+0

看到我上面的評論。 – Pyderman

+1

@pyderman您不能添加一行並保存該文件。它會創建一個同名的新文件 – haifzhan

+0

有道理;我想知道E先生如何能夠用文本編輯器實現它。 – Pyderman

1

follow()發電機只會在調用follow()後返回寫入文件的行。 seek(0,2)將光標置於該文件的末尾,然後嘗試從該位置讀取新行。

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 
+0

做得很好。這是一個守護者。 – Pyderman