【问题标题】:How to read the last few lines within a file using Python?如何使用 Python 读取文件中的最后几行?
【发布时间】:2016-01-25 11:12:51
【问题描述】:

我正在读取具有特定文件名的文件夹。我正在读取文件中的内容,但是如何读取文件中的特定行或最后 6 行?

************************************
     Test Scenario No. 1
     TestcaseID = FB_71125_1
     dpSettingScript = FB_71125_1_DP.txt
************************************

Setting Pre-Conditions (DP values, Sqlite DB):

    cp /fs/images/nfs/FileRecogTest/MNT/test/Databases/FB_71125_1_device.sqlite $NUANCE_DB_DIR/device.sqlite
    "sync" twice.

Starting the test:

            0#00041511#0000000000# FILERECOGNITIONTEST: = testScenarioNo (int)1 =
            0#00041514#0000000000# FILERECOGNITIONTEST: = TestcaseID (char*)FB_71125_1 =
            0#00041518#0000000000# FILERECOGNITIONTEST: = dpSettingScript (char*)FB_71125_1_DP.txt =
            0#00041520#0000000000# FILERECOGNITIONTEST: = UtteranceNo (char*)1 =
            0#00041524#0000000000# FILERECOGNITIONTEST: = expectedEventData (char*)0||none|0||none =
            0#00041528#0000000000# FILERECOGNITIONTEST: = expectedFollowUpDialog (char*) =
            0#00041536#0000000000# FILERECOGNITIONTEST: /fs/images/nfs/FileRecogTest/MNT/test/main_menu.wav#MEDIA_COND:PAS_MEDIA&MEDIA_NOT_BT#>main_menu.global<#<FS0000_Pos_Rec_Tone><FS1000_MainMenu_ini1>
            0#00041789#0000000000# FILERECOGNITIONTEST: Preparing test data done
            0#00043768#0000000000# FILERECOGNITIONTEST: /fs/images/nfs/FileRecogTest/MNT/test/Framework.wav##>{any_device_name}<#<FS0000_Pos_Rec_Tone><FS1400_DeviceDisambig_<slot>_ini1>
            0#00044008#0000000000# FILERECOGNITIONTEST: Preparing test data done
            0#00045426#0000000000# FILERECOGNITIONTESTWARNING: expected >{any_device_name}<, got >lowconfidence1@FS1000_MainMenu<
         1900#00046452#0000000000# FILERECOGNITIONTESTERROR: expected <FS0000_Pos_Rec_Tone><FS1400_DeviceDisambig_<slot>_ini1>, got <FS0000_Misrec_Tone><FS1000_MainMenu_nm1_004><pause300><FS1000_MainMenu_nm_001>
            0#00046480#0000000000# FILERECOGNITIONTEST: Preparing test data done
            0#00047026#0000000000# FILERECOGNITIONTEST: Stopping dialog immediately

    [VCALogParser] Scenario 1 FAILED.

有人可以建议我如何阅读特定行或文件中的最后 6 行吗?

【问题讨论】:

  • 您是否同时使用python 2.7python 3.x ??!!
  • 你可以edit你的帖子。只包含 relevant 标签。你真的在使用iPython吗?什么版本的 Python?不要只包含所有带有“python”一词的标签。
  • 我使用的是python 2.7.3
  • @ram 请不要编辑您的问题以反映您的代码的当前状态,这会使您的问题对其他读者毫无价值。而是将其附加到您的问题中。
  • 对不起。我会改正的

标签: python regex python-2.7


【解决方案1】:

我可以想到两种方法。如果您的文件不是太大,您可以读取所有行,只保留最后六行:

f = open(some_path)
last_lines = f.readlines()[-6:]

但这真的是蛮力的。更聪明的做法是使用文件对象的seek() 方法进行猜测:

file_size = os.stat(some_path).st_size  # in _bytes_, so take care depending on encoding
f = open(some_path)
f.seek(file_size - 1000)  # here's the guess. Adjust with expected line length
last_lines = f.readline()[-6:]

【讨论】:

  • file_size = os.stat("C:\\Users\\hemanth_venkatappa\\Desktop\\TEST\\Language").st_size f = open("C:\\Users\\Desktop\ \TEST\\Language") f.seek(file_size - 1000) # 这是猜测。用预期的行长调整 last_lines = f.readline()[-6:] f.close() // 对吗?
  • 很好,但是你想使用相同的文件名来获取大小和内容!
【解决方案2】:

要读取单个文件的最后 6 行,您可以使用 Python 的 file.seek 移动到文件末尾附近,然后读取其余行。您需要确定最大行长可能是多少,例如1024 个字符。

seek 命令首先用于移动到文件末尾(不读入),tell 用于确定文件中的位置(因为我们在末尾,这将是长度)。然后它在文件中倒退并读入行。如果文件很短,则读入整个文件。

import os 

filename = r"C:\Users\hemanth_venkatappa\Desktop\TEST\Language\test.txt"
back_up = 6 * 1024      # Go back from the end more than 6 lines worth.

with open(filename, "r") as f_input:
    f_input.seek(0, os.SEEK_END)
    backup = min(back_up, f_input.tell())
    f_input.seek(-backup, os.SEEK_END)
    print f_input.readlines()[-6:]

使用with 将确保您的文件在之后自动关闭。使用 r 为文件路径添加前缀可避免您需要双反斜杠文件路径。

因此,要将其应用于您的目录遍历并将结果写入单独的输出文件,您可以执行以下操作:

import os
import re

back_up = 6 * 256       # Go back from the end more than 6 lines worth

directory = r"C:\Users\hemanth_venkatappa\Desktop\TEST\Language"
output_filename = r"C:\Users\hemanth_venkatappa\Desktop\TEST\output.txt"

with open(output_filename, 'w') as f_output:
    for dirpath, dirnames, filenames in os.walk(directory): 
        for filename in filenames:
             if filename.startswith('VCALogParser_output'): 
                cur_file = os.path.join(dirpath, filename)
                with open(cur_file, "r") as f_input:
                    f_input.seek(0, os.SEEK_END)
                    backup = min(back_up , f_input.tell())
                    f_input.seek(-backup, os.SEEK_END)
                    last_lines = ''.join(f_input.readlines()[-6:])
                    try:
                        summary = ', '.join(re.search(r'(\d+ warning\(s\)).*?(\d+ error\(s\)).*?(\d+ scenarios\(s\))', last_lines, re.S).groups())
                    except AttributeError:
                        summary = "No summary"
                    f_output.write('{}: {}\n'.format(filename, summary))

【讨论】:

  • 我收到一个错误:IOError: [Errno 13] Permission denied: 'C:\\Users\\hemanth_venkatappa\\Desktop\\TEST\\Lang'
  • 再次出现同样的错误:使用 open(filename, "r") as f_input: IOError: [Errno 13] Permission denied: 'C:\\Users\\hemanth_venkatappa\\Desktop\\TEST'
  • 我添加了一个可以与您的文件夹漫游一起使用的版本。
  • 谢谢!!!但是如何删除这些额外的东西,如 \n 以及如何在单独的行中提示:文件:VCALogParser_output_MNT.log ['\n', '[VCALogParser] 41 warning(s)\n', '[VCALogParser] 76 error(s )\n', '[VCALogParser] 33 个场景失败。\n', '\n ', '[VCALogParser] Exiting VCALogParser']
  • 是否可以在上面的输出中仅打印 41 个警告、76 个错误和 33 个场景失败?
【解决方案3】:

或者,本质上,使用 for 循环将行追加到数组中,然后从数组中删除第 n 个项目,例如:

array=[] f=open("file.txt","r") for lines in f:

array.append(f.readlines())

f.close() while len(array) > 5:

del array[0]

【讨论】:

  • 我不知道删除它的起始行数。有没有可能的解决方案?
  • 那是什么鬼?!立即删除这些废话!
  • @L_Pav:你的意图是好的,但array.append(f.readlines())del array[0] 都没有达到你的预期。请在发布前自行测试。
猜你喜欢
  • 2011-06-21
  • 2018-02-25
  • 1970-01-01
  • 2015-10-23
  • 1970-01-01
  • 2017-11-28
  • 2016-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多