2015-05-19 61 views
1

我想知道是否有一种简单的方法可以打开文件的倒数第二行。 f.seek给了我无尽的麻烦。我可以很容易地进入最后一线,但我无法弄清楚如何达到上面的线。打印到文件的倒数第二行

+0

假设你循环读一行一行来处理它们,就已经分配给'line'(在你阅读每一行的变量)后还后分配'line'另一个变种(说'prevline')。不涉及复制,只是一个链接到数据的名称(引用)。然后在循环结束时使用'prevline'。 – Pynchia

回答

3

假设该文件不是太大,内存是不是一个问题

open('file.txt').readlines()[-2]

1
def penultimate(file_path) 
    return open(file_path).read().splitlines()[len(open(file_path).read().splitlines()) - 2] 
2

您可以从文件末尾寻求并计算遇到的新行的数量,只要你打第二'\n'停止,并呼吁readline()

with open('foo.txt') as f: 
    end_count = 0 
    n = -1 
    while end_count != 2: 
     f.seek(n, 2) 
     if f.read(1) == '\n': 
      end_count += 1 
     n -= 1 
    print repr(f.readline()) 

对于这样一个文件:

first line 
second line 
third line 
fourth line 
I want this line 
last line 

的输出将是:

'I want this line\n' 
2

文件是字节在大多数系统的单个长串(一些具有叉,盘区或记录),留下线的概念,以更高的水平。更复杂的是,在所有平台上,结局并不一样。这意味着您必须阅读行以识别它们,特别是仅可使用tell()搜索()到您找到的位置的文本文件。

如果我们只是读倒数第二行,很简单:

alllines=fileobject.readlines() 
penultimateline=alllines[-2] 

这种方法加载整个文件到内存中。如果我们要替换文件的末尾,从倒数第二行,事情变得多毛:

pen,last = 0,0 
while True: 
    last,pen = fileobject.tell(), last 
    line = fileobject.readline() 
    if not line: 
    break 
# back up to the penultimate line 
fileobject.seek(pen) # Note: seek is *required* to switch read/write 
fileobject.truncate() 
fileobject.write("Ate last two lines, this is a new line.\n") 

如果你只是想读以任意顺序线,linecache可能会有所帮助。

这些都扫描整个文件。像tail这样的工具可能会进行另一种优化:在文件末尾读取数据,直到找到足够的换行符来标识所需的行。这种情况变得更加复杂,因为只能在二进制模式下工作,但行解析只能在文本模式下可预测地工作。这反过来意味着我们猜测文件被linesep分隔的可能是错误的; Python的通用换行支持只能在文本模式下运行。

backsearch=0 
lines=[] 
while len(lines)<=2: 
    backsearch+=200 
    fileobject.seek(-backsearch, 2) 
    if fileobject.tell()==0: 
    break # ran out of file while scanning backwards 
    lines=fileobject.read().split(os.linesep) 
fileobject.seek(-backsearch, 2) 
# Now repeat the earlier method, knowing you're only processing 
# the final part of the file.