【问题标题】:How to read the last line of a file in Python?如何在 Python 中读取文件的最后一行?
【发布时间】:2018-02-25 18:19:13
【问题描述】:

我有两个要求。

第一个要求-我想读取文件的最后一行并将最后一个值分配给python中的变量。

第二个要求-

这是我的示例文件。

<serviceNameame="demo" wsdlUrl="demo.wsdl" serviceName="demo"/>
<context:property-placeholder location="filename.txt"/>

我想从这个文件中读取内容,即 filename.txt,它将在 &lt;context:property-placeholder location= . 之后。并且想将该值分配给 python 中的变量。

【问题讨论】:

标签: python python-3.x python-2.7 file


【解决方案1】:

一个简单的解决方案,不需要将整个文件存储在内存中(例如使用file.readlines() 或等效结构):

with open('filename.txt') as f:
    for line in f:
        pass
    last_line = line

对于大文件,查找文件末尾并向后移动以查找换行符会更有效,例如:

import os

with open('filename.txt', 'rb') as f:
    try:  # catch OSError in case of a one line file 
        f.seek(-2, os.SEEK_END)
        while f.read(1) != b'\n':
            f.seek(-2, os.SEEK_CUR)
    except OSError:
        f.seek(0)
    last_line = f.readline().decode()

注意,文件必须以二进制模式打开,否则,it will be impossible to seek from the end。

【讨论】:

  • seek() 方法非常快,但并不容易理解它在做什么。 for 循环方法不是太慢且易于理解。但是,下一个最高投票答案的readlines() 方法比这里的for 方法略快。
  • @L S 如果您在足够大的文件(例如几兆字节)上尝试它,file.readlines() 将比简单的for 循环慢。对于较大的文件,它也可能会耗尽您的可用内存。
  • @EugeneYarmash 这是获取文件最后一行的好方法。通常,我不想要文件的最后一行,而是文件的倒数第二行或倒数第三行,所以我尝试通过将 -2 更改为 ''-n" 来将其概括为一个函数,但我得到了可变的答案,我认为这是因为它以字节为单位,我还没有完全理解代码。n=2 确实给出了最后一行,n=3 实际上确实给了我最后一行,但 n=4 给了我最后一行 9。你知道吗我在这里做错了什么?
  • @jpmorr 我认为您不想更改 -2s,我相信这些会一次将您移回一个字符(与 f.read(1).. .如果将它们更改为更大的值,则会跳过字符,因此会得到不稳定的结果。相反,我会修改 while 循环以包含匹配计数,以便它运行直到匹配 n 次。(基本上是 while 匹配
  • 我想知道在某些情况下是否可以稍微加快速度(加上非常适合处理不是每个字符一个字节的替代编码,如果这可能是任何问题的话with??) 而是将 f.seek 返回到一个正在运行的字符串中,而不是在之后执行 readline。我想这可能取决于具体情况。
【解决方案2】:

为什么不直接读取所有行并将最后一行存储到变量中?

with open('filename.txt', 'r') as f:
    last_line = f.readlines()[-1]

【讨论】:

  • 这是一个好方法。它不是很慢,比seek() 方法更容易理解,并且当包装在with 块中时,无需在文件上显式调用close()。
  • @LS 这样的效率如何?如果您的文件有数百万行,则必须读取数百万行。除了seek 或从文件末尾开始的方法之外的任何东西都非常低效。
【解决方案3】:

在具有tail 命令的系统上,您可以使用tail,对于大文件,这将使您无需读取整个文件。

from subprocess import Popen, PIPE
f = 'yourfilename.txt'
# Get the last line from the file
p = Popen(['tail','-1',f],shell=False, stderr=PIPE, stdout=PIPE)
res,err = p.communicate()
if err:
    print (err.decode())
else:
    # Use split to get the part of the line that you require
    res = res.decode().split('location="')[1].strip().split('"')[0]
    print (res)

注意:decode() 命令仅对python3 是必需的

res = res.split('location="')[1].strip().split('"')[0]

适用于python2.x

【讨论】:

    【解决方案4】:

    他不只是问如何读取文件中的行,或者如何将最后一行读入变量。他还询问如何从最后一行解析出一个子字符串,其中包含他的目标值。

    这是一种方法。这是最短的方法吗?不,但是如果您不知道如何对字符串进行切片,则应从学习此处使用的每个内置函数开始。这段代码会得到你想要的:

    # Open the file
    myfile = open("filename.txt", "r")
    # Read all the lines into a List
    lst = list(myfile.readlines())
    # Close the file
    myfile.close()
    # Get just the last line
    lastline = lst[len(lst)-1]
    # Locate the start of the label you want, 
    # and set the start position at the end 
    # of the label:
    intStart = lastline.find('location="') + 10
    # snip off a substring from the 
    # target value to the end (this is called a slice):
    sub = lastline[intStart:]
    # Your ending marker is now the 
    # ending quote (") that is located 
    # at the end of your target value.
    # Get it's index.
    intEnd = sub.find('"')
    # Finally, grab the value, using 
    # another slice operation.
    finalvalue = sub[0:intEnd]
    print finalvalue
    

    打印命令输出应如下所示:

    filename.txt
    

    此处涵盖的主题:

    • 读取文本文件
    • 根据内容制作 Python 行列表,以便使用从零开始的索引 len(List) -1 轻松获取最后一行。
    • 使用find获取字符串在字符串中的索引位置
    • 使用slice获取子字符串

    所有这些主题都在 Python 文档中 - 这里没有任何额外内容,也不需要导入来使用这里使用的内置函数。

    干杯,
    -=卡梅隆

    【讨论】:

      【解决方案5】:

      进行大小检查,如果文件至少包含这么多字节,则从文件末尾向后查找一定数量的字节:

        with open(filename, 'rb') as myfile:
            if os.path.getsize(filename) > 200:
               myfile.seek(-200, 2)
            line = myfile.readlines()[-1].decode("utf-8")
      

      在 python3 中需要以二进制模式打开,它不能进行非零端相对查找。 myfile.seek(-200, 2) 将当前文件指针放置在文件末尾前 200 个字符 (2), 然后最后一行 [-1] 取自 readlines() 并解码。

      【讨论】:

        【解决方案6】:

        来自https://docs.python.org/3/library/collections.html的示例

        from collections import deque
        
        def tail(filename, n=10):
            'Return the last n lines of a file'
            with open(filename) as f:
                return deque(f, n) 
        

        【讨论】:

        • 这将逐行读取整个文件。这可以节省内存,但对于大文件来说不会很快。
        • 大文件怎么样你需要考虑如何高效地处理大文件和小内存指纹
        【解决方案7】:

        您可以通过以下方式阅读和编辑所有行:

        file = open('your_file.txt', 'r')
        read_file = file.readlines()
        file.close()
        
        file1 = open('your_file.txt', 'w')
        
        var = 'filename.txt'
        
        for lec in range(len(read_file)):
            if lec == 1:
                file1.write('<context:property-placeholder location="%s"/>' % var)
            else:
                file1.write(read_file[lec])
        file1.close()
        

        【讨论】:

        • 感谢您的回复。 .它会在当前目录中创建一个新文件(filename.txt)吗?如果是..我不想在当前目录中创建新文件。
        • 感谢您的回复。 .它会在当前目录中创建一个新文件(filename.txt)吗?如果是..我不想在当前目录中创建新文件。
        • 不,它不会,只是编辑现有的。要理解,首先我们阅读,然后我们编写它。我忘记了什么,关闭 file1.close()
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-20
        • 2010-10-04
        • 1970-01-01
        • 2022-09-23
        • 1970-01-01
        相关资源
        最近更新 更多