import re import os def split_log_file(source_folder: str, output_folder: str) -> list: """ 扫描源文件夹中的所有.txt聊天记录,将它们按天合并,并在每条记录前标注来源群组。 此函数会先清空旧的拆分文件,以确保报告的实时性。 :param source_folder: 存放原始聊天记录的文件夹路径 (例如: 'uploads')。 :param output_folder: 存放按天合并后文件的文件夹路径 (例如: '聊天记录_按天拆分')。 :return: 一个包含所有被写入的每日合并文件路径的列表。 """ if not os.path.exists(source_folder): print(f"错误: 源文件夹未找到 -> {source_folder}") return [] if not os.path.exists(output_folder): os.makedirs(output_folder) print(f"已创建输出文件夹: {output_folder}") # **第一步:先清空所有旧的每日日志文件,确保数据是全新的** for f_name in os.listdir(output_folder): if re.match(r"^\d{4}-\d{2}-\d{2}\.txt$", f_name): try: os.remove(os.path.join(output_folder, f_name)) except OSError as e: print(f"警告:无法删除旧的日志文件 {f_name}。错误: {e}") print("已清空旧的每日合并日志。") date_pattern = re.compile(r"^(\d{4}-\d{2}-\d{2}) \d{2}:\d{2}:\d{2}") # 用一个字典来管理所有按天拆分的输出文件句柄,避免频繁开关文件 output_files = {} # 用一个集合来存储本次运行实际写入过的文件路径 written_files = set() try: source_file_names = [f for f in os.listdir(source_folder) if f.endswith('.txt')] if not source_file_names: print(f"警告: 源文件夹 '{source_folder}' 中未发现 .txt 文件。") return [] # **第二步:遍历所有源文件并处理** for filename in source_file_names: source_file_path = os.path.join(source_folder, filename) # 从文件名提取群名,作为来源标签 group_name = os.path.splitext(filename)[0] source_tag = f"[来自: {group_name}] " # 记录当前文件最后一次匹配到的日期所对应的输出文件句柄 current_day_output_file = None with open(source_file_path, 'r', encoding='utf-8') as f_in: for line in f_in: # 忽略空行 if not line.strip(): continue match = date_pattern.match(line) if match: date_str = match.group(1) # 如果需要切换到新的日期文件 if date_str not in output_files: output_filename = os.path.join(output_folder, f"{date_str}.txt") # 因为已清空旧文件,这里统一使用安全追加模式 output_files[date_str] = open(output_filename, 'a', encoding='utf-8') written_files.add(output_filename) # 更新当前行应该写入的文件 current_day_output_file = output_files[date_str] # 如果当前行已经有了归属文件 (无论是新找到的还是继承上一行的) # 这可以确保多行消息也能被正确地打上标签并写入 if current_day_output_file: current_day_output_file.write(source_tag + line) finally: # **第三步:操作结束后,关闭所有打开的文件,释放资源** for f in output_files.values(): f.close() print(f"日志合并与拆分完成。共处理 {len(source_file_names)} 个源文件,写入了 {len(written_files)} 个每日日志。") return list(written_files)