python递归遍历文件夹 python递归读取文件
论文详细介绍了如何使用Python遍历遍历目录下的.txt文件,并高效地解析和格式化网络速度的数据。通过将文件内容按固定行分块处理,并结合专门的函数进行数据提取、类型转换和格式化输出,实现对下载和上传速度的精确分析与报告。该方法适用于处理内部结构一致的大量文本文件。1. 问题背景与分析
在日常的数据处理任务中,我们经常需要从具有大量相似结构但内容各异的文本文件中提取特定信息。本教程给出一个具体场景例如:从一个包含多层子目录的系统中,查找所有.txt文件。每个.txt文件都包含两个逻辑部分,每个部分由固定数量的行组成,并以特定的标识符(例如gt;)分隔。我们的目标是从每个部分的特定行中,提取“下载速度”和“上传速度”的数据,并根据其分值条件进行判断和整理输出。
示例文件结构如下,其中逻辑部分(由gt;引导)固定包含8行:gt;这是第一个输出和一些其他内容这些是一些测试线来填充文件测试下载速度Download:0.00 Mbit/s测试上传速度Upload: 0.00 Mbit/sgt;这是第二个输出,但其他文本都在这里,这些是一些测试行来填充文件测试下载速度下载: 1200.58 Mbit/s测试上传速度Upload:857.25 Kbit/s登录后复制
我们需要对每个文件的每个部分的“下载:”和“上传:”进行进行解析,取出值和单位,并根据预设的条件(例如速度默认、小于600 Mbit/s等)输出不同的信息。2. 解决方案概述
为了并健壮地解决此类问题高效,采用我们以下策略:梯度文件查找:使用pathlib库递归地查找所有目标文件。文件内容分块:由于文件结构一致,每个逻辑部分行数固定,我们可以将文件按固定大小划分,将每个逻辑部分视为一个独立的数据块。数据提取与转换:编写辅助内容函数,从指定行中解析出速度浮点数(浮点数)和单位(字符串)。结果格式化:编写辅助函数,根据提取的速度值和单位,生成符合要求的输出字符串。优选设计:将不同的功能封装在独立的函数中,提高代码的实用性和可维护性。3. 具体实现步骤3.1 定义常量与文件查找
首先,需要我们定义文件中每个逻辑部分的行数以及文件包含的逻辑部分数量。然后,使用pathlib库进行分层文件查找。
立即学习“Python免费学习笔记(深入)”;import sysfrom pathlib import Path#定义常量:每个逻辑部分的行数,以及文件包含的逻辑部分数量LINES_PER_PART = 8PARTS_PER_FILE = 2 #根据样本文件,每个文件有两个部分 def main(): # 跳转当前目录及其子目录下所有.txt文件 result = list(Path(quot;.quot;).rglob(quot;*.txtquot;)) for filename in result: with open(filename, 'r') as file: # 读取文件所有行lines = file.readlines() # ...后续处理 ...登录后复制3.2内容文件分块函数
为了将文件的所有行按固定大小(LINES_PER_PART)分割成多个逻辑部分,我们定义了一个块函数。def chunks(arr, chunk_size): quot;quot;quot;将列表 arr 分割成大小为 chunk_size 的块。 quot;quot;quot; result = [] for i in range(0, len(arr), chunk_size): result.append(arr[i:i chunk_size]) return result登录后复制
在main函数中调用此函数:# ... (在main函数内部)lines = file.readlines() parts = chunks(lines, LINES_PER_PART) # 将文件内容分块# ... 登录后复制3.3速度信息解析函数
parse_speed_info函数负责从包含速度信息的字符串中提取数值和单位。它设速度值为字符串的第二个单词,单位为第三个单词。def parse_speed_info(string): quot;quot;quot;从速度信息字符串中解析出速度值(浮点数)和单位。
示例输入: quot;下载: 1200.58 Mbit/s\nquot; 示例输出: (1200.58, quot;Mbit/转换squot;) quot;quot;quot; # 忽略 quot;下载:quot; 或 quot;上传:quot; 部分,从个单词开始解析 speed_info_list = string.split()[1::] # 返回速度值(第二为浮点数)和单位return ( float(speed_info_list[0]), speed_info_list[1].strip() # 删除单位补充的换行符 ) 登录后复制3.4速度信息格式化函数
stringify_speed_info函数根据解析出的速度值和单位,生成符合特定条件(如零、小于600)的报告字符串。def stringify_speed_info(speed,unit): quot;quot;quot;根据速度值和单位,生成格式化的输出字符串。 quot;quot;quot; if speed == 0: return quot;zeroquot; elif unit == quot;Mbit/squot; and speed lt; 600.0: # 仅对 Mbit/s 单位进行小于 600 的判断 return fquot;小于 600 {unit}quot; else: return fquot;{speed} {unit}quot;登录后复制
注意:原始问题中对“小于 600”的判断仅针对 Mbit/s单位,此处已在代码中表示。3.5 遍历分块速度并输出结果
在主函数中,遍历parts列表,对每个逻辑部分提取并处理下载和上传速度信息。根据示例文件结构,下载信息在倒数第3行(part[-3]),上传速度信息在最后一行(part[-1])。
# ... (在 main 函数内部) parts = chunks(lines, LINES_PER_PART) for i,part in enumerate(parts, 1): # i 从 1 开始统计,表示第几部分 # 下载信息在当前部分的速度倒数第三行 download_info = parse_speed_info(part[-3]) # 上传速度信息在当前部分的最后一行 upload_info = parse_speed_info(part[-1]) # 打印导出后的结果print(fquot;{filename}的下载{i}速度为{stringify_speed_info(*download_info)}.quot;) print(fquot;{filename}的上传{i}速度为{stringify_speed_info(*upload_info)}.quot;) print() # 每处理完一个文件的一部分后打印空行# ...登录后复制3.6完整代码
将上述所有部分整合,完整形成Python脚本。#!/usr/bin/python3from pathlib import Path# 定义常量:每个逻辑部分的行数 LINES_PER_PART = 8def chunks(arr, chunk_size): quot;quot;quot;将列表 arr 分割成大小为 chunk_size 的块。 quot;quot;quot; result = [] for i in range(0, len(arr), chunk_size): result.append(arr[i:i chunk_size]) return resultdef parse_speed_info(string): """从速speed_info_list[1].strip() # 删除单位消耗的换行符 )def stringify_speed_info(speed,unit): """ 根据速度值和单位,生成格式化的输出字符串。
""" if speed == 0: return "zero" elif unit == "Mbit/s" and speed < 600.0: return f"less than 600 {unit}" else: return f"{speed} {unit}" def main(): """ 主函数:执行文件查找、解析和结果输出。
""" # 多层查找当前目录及其子目录下所有.txt文件 result = list(Path(".").rglob("*.txt")) for filename in result: try: with open(filename, 'r') as file:lines = file.readlines() # 将文件按固定行数分块内容 parts = chunks(lines, LINES_PER_PART) # 遍历每个逻辑部分 for i,part in enumerate(parts,parts, 1): # 检查部分行数是否符合预期,索引错误 if len(part) != LINES_PER_PART: print(f"Warning: 文件 {filename},第 {i} 部分有意外行数 ({len(part)} 行)。跳过。") continue # 下载速度信息在当前部分的倒数第三行 download_info = parse_speed_info(part[-3]) # 上传速度信息在当前部分的最后一行 upload_info = parse_speed_info(part[-1]) # 打印格式化后的结果 print(f"{filename} 的下载{i}速度为 {stringify_speed_info(*download_info)}.") print(f"{filename} 的上传{i}速度为 {stringify_speed_info(*upload_info)}.") print() # 每处理完一个文件的一部分后打印空行 except Exception as e: print(f"处理文件 {filename} 时出错: {e}", file=sys.stderr)if __name__ == "__main__": main()登录后复制4. 注意事项与总结文件结构一致性:本方案的核心假设是所有.txt文件都具有严格一致的内部结构,即每个逻辑部分都包含固定数量的行(LINES_PER_PART),并且速度信息始终位于这些部分的固定相对位置。如果文件结构不一致,例如行数不固定或信息位置变化,则需要更复杂的解析逻辑(如基于正表达式或关键词搜索)。
错误处理:在完整代码中加入了简单的try- except块来捕获文件打开或处理过程中的异常,并增加了对部分长度的检查,以提高程序的健壮性。在实际应用中,可以根据需求增加更详细的错误日志记录和处理机制。内存效率:对于非常大的文件,file.readlines()会立即将所有内容加载到内存中。如果文件大小达到GB每个级别,这可能会导致内存溢出。对于这种情况,可以考虑逐行读取文件,并使用一个像素来构建每个部分,或者使用生成器(yield)来优化块函数,实现说明加载。但对于本例中文件只有两部分、每部分 8 行的场景,readlines() 是完全合适的。可扩展性: 通过将解析和初始化逻辑封装在单独的函数中进行维护,代码的判断性和可性得到了显着的提升。如果将来需要提取其他类型数据的或改变输出格式,只需修改相应的函数即可,而无需完成主处理逻辑。
通过上述方法,我们能够高效、准确地从整理文本文件中提取所需数据,并根据业务逻辑进行灵活的展示。这种分而治之、精细设计的思想在处理复杂数据解析任务时至关重要。
以上就是使用Python队列处理格式化文本文件并提取特定数据的详细内容,更多请关注乐哥常识网相关文章!