【问题标题】:Printing to the penultimate line of a file打印到文件的倒数第二行
【发布时间】:2015-05-19 11:41:48
【问题描述】:

我想知道是否有一种简单的方法可以到达打开文件的倒数第二行。 f.seek 给我带来了无穷无尽的麻烦。我可以轻松到达最后一行,但我不知道如何到达最后一行。

【问题讨论】:

  • 假设你循环读取一行一行来处理它们,就在分配给line(你读取每一行的变量)之后,还将line分配给另一个变量(比如prevline )。不涉及复制,只是链接到数据的名称(参考)。然后在循环结束时使用prevline

标签: python file seek


【解决方案1】:

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

open('file.txt').readlines()[-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'
    

    【讨论】:

      【解决方案3】:

      在大多数系统(有些系统有分叉、扩展或记录)上,文件是一长串字节,将行的概念留给了更高的层次。更复杂的是,行尾在所有平台上看起来都不一样。这意味着您必须阅读这些行来识别它们,特别是对于文本文件,您只能通过 seek() 找到使用 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. 
      

      【讨论】:

        【解决方案4】:
        def penultimate(file_path)
            return open(file_path).read().splitlines()[len(open(file_path).read().splitlines()) - 2]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-03-17
          • 2018-01-21
          • 2011-01-06
          • 1970-01-01
          • 2022-06-27
          • 1970-01-01
          • 2021-02-23
          • 2016-10-10
          相关资源
          最近更新 更多