如何判断Scrapy及大文件去重CMD命令是否运行并显示进度
解决大文本文件去重时的进度显示问题
我懂你这种焦虑——处理240MB的大文件时,CMD里只有个闪烁的光标,完全不知道程序是在卖力干活还是已经卡死了。咱们可以给代码加个进度跟踪的逻辑,不仅能实时看到处理状态,还能优化原代码的内存占用(毕竟一次性把整个大文件读进内存,对资源消耗实在不友好)。
优化思路
- 逐行处理替代全量读取:原代码一次性把所有内容读进内存,大文件场景下内存压力大,还没法跟踪进度。改成逐行读取,既能降低内存占用,又能统计处理行数。
- 实时进度提示:通过统计总行数计算进度百分比,或者直接显示已处理行数,用单行刷新的方式在CMD里输出,避免刷屏。
- 高效去重:用集合
seen_words跟踪已出现的单词,确保每个单词只保留首次出现的实例。
代码实现(保留唯一单词顺序+进度提示)
下面的代码会按单词首次出现的顺序保留所有唯一词汇,同时实时显示处理进度:
import sys def remove_redundancy_with_progress(input_file, output_file): # 先统计总行数,用于计算精确进度(如果觉得耗时可以跳过这步) total_lines = 0 with open(input_file, 'r', encoding='utf-8-sig') as f: for _ in f: total_lines += 1 print(f"开始处理,总共有 {total_lines} 行内容") seen_words = set() unique_words_ordered = [] processed_lines = 0 with open(input_file, 'r', encoding='utf-8-sig') as in_f: for line in in_f: processed_lines += 1 # 拆分当前行的单词 words = line.strip().split() # 过滤并收集未出现过的单词 for word in words: if word not in seen_words: seen_words.add(word) unique_words_ordered.append(word) # 每处理1%的行就更新一次进度(避免频繁输出) update_interval = max(1, total_lines // 100) if processed_lines % update_interval == 0: progress = (processed_lines / total_lines) * 100 # 用\r实现单行刷新,保持CMD界面整洁 sys.stdout.write( f"\r已处理 {processed_lines}/{total_lines} 行 | 已收集 {len(unique_words_ordered)} 个唯一单词 | 进度: {progress:.1f}%" ) sys.stdout.flush() # 将结果写入输出文件 with open(output_file, 'w', encoding='utf-8-sig') as out_f: out_f.write(' '.join(unique_words_ordered)) print("\n处理完成!最终共保留了 {} 个唯一单词".format(len(unique_words_ordered))) # 调用函数,替换成你的文件名 remove_redundancy_with_progress("nahidd.txt", "nahidd_pure.txt")
可选调整
- 跳过总行数统计:如果觉得统计总行数太耗时,可以删掉这部分逻辑,把进度提示改成只显示已处理行数和已收集的单词数:
# 去掉总行数统计的代码,进度提示改成: sys.stdout.write( f"\r已处理 {processed_lines} 行 | 已收集 {len(unique_words_ordered)} 个唯一单词" ) - 保留原文件行结构:如果你需要保留原文件的行分隔,只是每行只保留未出现过的单词,可以调整代码为逐行写入过滤后的内容,同样加上进度提示即可。
为什么比原代码更好?
- 内存占用低:逐行处理不会把整个大文件加载到内存,适合大文件场景。
- 状态可视化:实时看到处理进度,再也不用瞎等。
- 效率更高:集合的查找是O(1)操作,比原代码先转集合再排序的方式更高效。
内容的提问来源于stack exchange,提问作者Nahid Hossain
相关产品推荐
相关产品推荐

