diff . patch备用

使用diff与patch进行文件更新
单个文件


diff –uN from-file to-file >to-file.patch


patch –p0 < to-file.patch


patch –RE –p0 < to-file.patch


多个文件


diff –uNr from-docu to-docu >to-docu.patch


patch –p1 < to-docu.patch


patch –R –p1 <to-docu.patch
还是不对,从warn.csv中复制,要按照对应列名去复制到对应的列中,而不是全部复制。winmerge未生成报告:[Running] python -u "e:\system\Desktop\项目所需文件\工具\ffff\File Diff & Excel Update.py" ================================================== 开始文件比较... 报告文件路径: e:\system\Desktop\项目所需文件\工具\ffff\temp\winmerge_diff_report.txt 正在比较目录: E:\system\Desktop\项目所需文件\工具\ffff\code\old\GA_D82DD83D_00-00-07\mainline\spa_traveo\src 和 E:\system\Desktop\项目所需文件\工具\ffff\code\new\GA_D82DD83D_00-00-08\mainline\spa_traveo\src 执行命令: "E:/App/WinMerge/WinMerge/WinMergeU.exe" /u /r /minimize /noprefs /noninteractive /report="e:\system\Desktop\项目所需文件\工具\ffff\temp\winmerge_diff_report.txt" "E:\system\Desktop\项目所需文件\工具\ffff\code\old\GA_D82DD83D_00-00-07\mainline\spa_traveo\src" "E:\system\Desktop\项目所需文件\工具\ffff\code\new\GA_D82DD83D_00-00-08\mainline\spa_traveo\src" WinMerge退出代码: 0 WinMerge stdout: 空 WinMerge stderr: 空 警告: WinMerge未生成报告文件 e:\system\Desktop\项目所需文件\工具\ffff\temp\winmerge_diff_report.txt,尝试从标准输出获取 报告内容为空,无差异文件 找到 0 个变更文件 ================================================== 更新Excel表格... 开始更新Excel: E:\system\Desktop\项目所需文件\工具\ffff\GA_D24D_00-00-01(三回目)_QAC.xlsx 发现现有Excel文件: E:\system\Desktop\项目所需文件\工具\ffff\GA_D24D_00-00-01(三回目)_QAC.xlsx 成功加载现有Excel文件 === 功能1: 写入文件差分表 === 已将 0 个变更文件路径写入'ファイル差分'工作表 === 功能2: 复制func_met.csv到_org_fm工作表 === 已将func_met.csv内容(4137行)复制到'_org_fm'工作表 === 功能3: 处理warn.csv并添加变更标记 === 已处理 1000 行警告数据... 已处理 2000 行警告数据... 已处理 3000 行警告数据... 已处理 4000 行警告数据... 已处理 5000 行警告数据... 已处理 6000 行警告数据... 已处理 7000 行警告数据... 已处理 8000 行警告数据... 已处理 9000 行警告数据... 已处理 10000 行警告数据... 已处理 11000 行警告数据... 已处理 12000 行警告数据... 已处理 13000 行警告数据... 已处理 14000 行警告数据... 已处理 15000 行警告数据... 已完成 15471 行警告数据处理 已将warn.csv内容(15471行)写入'warn'工作表 成功保存Excel: E:\system\Desktop\项目所需文件\工具\ffff\GA_D24D_00-00-01(三回目)_QAC.xlsx 处理完成! 输出文件: E:\system\Desktop\项目所需文件\工具\ffff\GA_D24D_00-00-01(三回目)_QAC.xlsx ================================================== 程序结束 代码如下:import os import re import subprocess import pandas as pd from openpyxl import load_workbook, Workbook from openpyxl.utils.dataframe import dataframe_to_rows import difflib import sys import io import time import shutil from pathlib import Path # 设置系统标准输出为UTF-8 sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace') sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace') def get_changed_files_and_lines(old_dir, new_dir, winmerge_path, save_report=True): """使用WinMerge获取变更文件列表及具体变更行号(改进版)""" # 创建临时目录存放报告 temp_dir = os.path.join(os.path.dirname(__file__), "temp") os.makedirs(temp_dir, exist_ok=True) report_file = os.path.join(temp_dir, "winmerge_diff_report.txt") print(f"报告文件路径: {report_file}") # 移除路径结尾的反斜杠 old_dir = old_dir.rstrip('\\') new_dir = new_dir.rstrip('\\') print(f"正在比较目录: {old_dir} 和 {new_dir}") # 改进的WinMerge命令参数 - 强制生成报告 cmd = [ f'"{winmerge_path}"', '/u', # 使用Unicode '/r', # 递归比较子目录 '/minimize', # 最小化窗口 '/noprefs', # 不加载GUI偏好设置 '/noninteractive', # 非交互模式 f'/report="{report_file}"', # 官方推荐的报告参数 f'"{old_dir}"', f'"{new_dir}"' ] full_cmd = ' '.join(cmd) print(f"执行命令: {full_cmd}") changed_files = {} try: # 运行WinMerge result = subprocess.run( full_cmd, shell=True, timeout=600, # 10分钟超时 stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding='utf-8', errors='ignore' ) # 检查WinMerge退出代码 (0=相同, 1=有差异, >1=错误) print(f"WinMerge退出代码: {result.returncode}") print(f"WinMerge stdout: {result.stdout[:200] if result.stdout else '空'}") print(f"WinMerge stderr: {result.stderr[:200] if result.stderr else '空'}") # 检查报告文件是否生成 if not os.path.exists(report_file): print(f"警告: WinMerge未生成报告文件 {report_file},尝试从标准输出获取") report_content = result.stdout else: file_size = os.path.getsize(report_file) print(f"报告文件大小: {file_size} 字节") # 尝试读取报告文件 try: with open(report_file, 'r', encoding='utf-16') as f: report_content = f.read() print(f"成功读取报告文件(UTF-16)") except UnicodeError: try: with open(report_file, 'r', encoding='utf-8') as f: report_content = f.read() print(f"成功读取报告文件(UTF-8)") except Exception as e: print(f"读取报告文件失败: {e}") report_content = result.stdout # 仅当有内容时处理 if not report_content.strip(): print(f"报告内容为空,无差异文件") return changed_files # 保存报告内容以供检查 if save_report: with open(os.path.join(temp_dir, "report_content.txt"), "w", encoding="utf-8") as f: f.write(report_content) print(f"已将报告内容保存至: {os.path.join(temp_dir, 'report_content.txt')}") # 提取所有差异文件 diff_files = set() # 增强的正则表达式 patterns = [ re.compile(r'文件\s+["\']?(.+?)["\']?\s+和\s+["\']?(.+?)["\']?\s+不同'), # 中文格式 re.compile(r'Files\s+["\']?(.+?)["\']?\s+and\s+["\']?(.+?)["\']?\s+differ'), # 英文格式 re.compile(r'Comparing\s+["\']?(.+?)["\']?\s+and\s+["\']?(.+?)["\']?'), re.compile(r'File\s+["\']?(.+?)["\']?\s+and\s+["\']?(.+?)["\']?\s+are different') ] for line in report_content.splitlines(): matched = False for pattern in patterns: match = pattern.search(line) if match: # 提取新版本文件路径 new_file = match.group(2).strip() # 规范化路径 new_file = os.path.normpath(new_file) print(f"识别到差异文件: {new_file}") diff_files.add(new_file) matched = True break if not matched and ("不同" in line or "differ" in line or "different" in line or "Comparing" in line): print(f"[未匹配行] {line}") print(f"发现 {len(diff_files)} 个差异文件") # 获取变更行号 for file_path in diff_files: # 构建旧文件路径 rel_path = os.path.relpath(file_path, new_dir) old_file_path = os.path.join(old_dir, rel_path) # 检查文件是否存在 if not os.path.isfile(old_file_path): print(f"旧文件不存在: {old_file_path}") continue if not os.path.isfile(file_path): print(f"新文件不存在: {file_path}") continue # 比较文件内容差异 changed_lines = set() try: print(f"比较文件: {old_file_path} vs {file_path}") with open(old_file_path, 'r', encoding='utf-8', errors='ignore') as f_old: content_old = f_old.readlines() with open(file_path, 'r', encoding='utf-8', errors='ignore') as f_new: content_new = f_new.readlines() # 使用更精确的diff解析方法 differ = difflib.Differ() diff = list(differ.compare(content_old, content_new)) line_num = 0 for line_diff in diff: # 计算新文件中的行号 if line_diff.startswith(' '): line_num += 1 # 未更改的行 elif line_diff.startswith('+'): line_num += 1 changed_lines.add(line_num) elif line_diff.startswith('-'): # 删除行不影响新文件行号 pass except Exception as e: print(f"错误比较文件 {old_file_path} 和 {file_path}: {str(e)}") import traceback traceback.print_exc() # 使用相对路径作为键 changed_files[rel_path] = changed_lines print(f"变更文件: {rel_path} - {len(changed_lines)} 行变更") except subprocess.TimeoutExpired: print("WinMerge执行超时,强制终止") except Exception as e: print(f"处理报告文件时出错: {str(e)}") import traceback traceback.print_exc() return changed_files def detect_encoding(file_path): """检测文件编码""" # 常见编码类型列表(可根据需要扩展) encodings = ['utf-8', 'shift_jis', 'cp932', 'latin1', 'iso-8859-1', 'euc-jp'] for encoding in encodings: try: with open(file_path, 'r', encoding=encoding) as f: f.read(1024) # 仅读取部分内容测试 return encoding except UnicodeDecodeError: continue return 'utf-8' # 默认使用utf-8 def update_excel_sheets(csv_folder, output_excel, changed_files): """更新Excel表格实现三个主要功能""" try: print(f"开始更新Excel: {output_excel}") # 加载或创建Excel文件 if os.path.exists(output_excel): print(f"发现现有Excel文件: {output_excel}") try: wb = load_workbook(output_excel) print("成功加载现有Excel文件") except Exception as e: print(f"加载Excel失败: {e},将创建新文件") # 备份策略 timestamp = time.strftime("%Y%m%d_%H%M%S") backup_name = f"{output_excel}.bak_{timestamp}" try: shutil.copy2(output_excel, backup_name) print(f"已将损坏文件备份至: {backup_name}") except Exception as backup_error: print(f"备份文件时出错: {backup_error}") wb = Workbook() # 创建必需的工作表 required_sheets = ["ファイル差分", "_org_fm", "warn"] for sheet in required_sheets: if sheet not in wb.sheetnames: wb.create_sheet(sheet) else: print("创建新的Excel文件") wb = Workbook() # 创建所需的工作表 wb.create_sheet("ファイル差分") wb.create_sheet("_org_fm") wb.create_sheet("warn") # 功能1: 将变更文件路径写入"ファイル差分"工作表 print("\n=== 功能1: 写入文件差分表 ===") if "ファイル差分" not in wb.sheetnames: wb.create_sheet("ファイル差分") print("创建'ファイル差分'工作表") ws_diff = wb["ファイル差分"] # 清除现有内容但保留标题 if ws_diff.max_row > 1: ws_diff.delete_rows(2, ws_diff.max_row - 1) # 确保有标题行 if ws_diff.max_row == 0 or ws_diff["A1"].value != "文件路径": ws_diff.append(["文件路径"]) # 写入所有变更文件路径 for file_path in changed_files.keys(): ws_diff.append([file_path]) print(f"已将 {len(changed_files)} 个变更文件路径写入'ファイル差分'工作表") # 功能2: 复制func_met.csv到_org_fm工作表 print("\n=== 功能2: 复制func_met.csv到_org_fm工作表 ===") func_met_path = os.path.join(csv_folder, "func_met.csv") if not os.path.exists(func_met_path): print(f"警告: 未找到func_met.csv文件 - {func_met_path}") else: if "_org_fm" not in wb.sheetnames: wb.create_sheet("_org_fm") print("创建'_org_fm'工作表") ws_fm = wb["_org_fm"] # 清除现有内容但保留列标题 if ws_fm.max_row > 1: ws_fm.delete_rows(2, ws_fm.max_row - 1) # 读取CSV文件 encoding = detect_encoding(func_met_path) df_fm = pd.read_csv(func_met_path, encoding=encoding) # 写入数据行 for _, row in df_fm.iterrows(): ws_fm.append(list(row)) print(f"已将func_met.csv内容({len(df_fm)}行)复制到'_org_fm'工作表") # 功能3: 处理warn.csv并添加变更标记(改进版) print("\n=== 功能3: 处理warn.csv并添加变更标记 ===") warn_path = os.path.join(csv_folder, "warn.csv") if not os.path.exists(warn_path): print(f"警告: 未找到warn.csv文件 - {warn_path}") else: if "warn" not in wb.sheetnames: wb.create_sheet("warn") print("创建'warn'工作表") ws_warn = wb["warn"] # 清除现有内容但保留第一行(标题行) if ws_warn.max_row > 2: # 保留前两行(第一行标题,第二行列名) ws_warn.delete_rows(3, ws_warn.max_row - 2) # 读取CSV文件 encoding = detect_encoding(warn_path) df_warn = pd.read_csv(warn_path, encoding=encoding) # 添加WarnFilter(变更有无)列 df_warn['WarnFilter(变更有无)'] = 'No' # 列名映射(Excel第二行 -> CSV第一行) column_mapping = { 'Source': 'File', 'Line #': 'Line', 'Level': 'Grp', 'Warn #': 'Nbr', 'Message': 'Description' } # 重命名列以匹配Excel的第二行 renamed_columns = [] for col in df_warn.columns: # 反向映射:将CSV列名映射为Excel列名 for excel_col, csv_col in column_mapping.items(): if col == csv_col: renamed_columns.append(excel_col) break else: renamed_columns.append(col) # 保持原名 df_warn.columns = renamed_columns # 确保所有列都存在 required_columns = ['Source', 'Line #', 'Level', 'Warn #', 'Message'] for col in required_columns: if col not in df_warn.columns: print(f"警告: 缺少必要列 {col},添加空列") df_warn[col] = "" # 构建变更文件映射(filename -> changed_lines) file_map = {} for file_path, changed_lines in changed_files.items(): filename = Path(file_path).name file_map[filename] = changed_lines # 处理每一行 processed_count = 0 for index, row in df_warn.iterrows(): source = str(row.get('Source', '')) if not source or pd.isna(source): continue # 从源路径中提取文件名 filename = Path(source).name # 检查是否在变更文件列表中 if filename in file_map: try: line_num = int(row.get('Line #', 0)) if line_num and line_num in file_map[filename]: df_warn.at[index, 'WarnFilter(变更有无)'] = 'Yes' except (ValueError, TypeError): pass # 进度跟踪 processed_count += 1 if processed_count % 1000 == 0: print(f"已处理 {processed_count} 行警告数据...") print(f"已完成 {len(df_warn)} 行警告数据处理") # 写入数据到Excel(从第三行开始) # 第一行:标题(保留) # 第二行:列名(保留) # 第三行开始:数据 # 获取当前行数(已有两行) start_row = ws_warn.max_row + 1 if ws_warn.max_row > 0 else 3 # 批量写入数据 for i, row in enumerate(dataframe_to_rows(df_warn, index=False, header=False)): ws_warn.append(row) print(f"已将warn.csv内容({len(df_warn)}行)写入'warn'工作表") # 保存Excel wb.save(output_excel) print(f"成功保存Excel: {output_excel}") return True except Exception as e: print(f"更新Excel出错: {str(e)}") import traceback traceback.print_exc() return False def main(): # 配置路径(根据实际情况修改) old_code_dir = r"E:\system\Desktop\项目所需文件\工具\ffff\code\old\GA_D82DD83D_00-00-07\mainline\spa_traveo\src" new_code_dir = r"E:\system\Desktop\项目所需文件\工具\ffff\code\new\GA_D82DD83D_00-00-08\mainline\spa_traveo\src" csv_folder = r"E:\system\Desktop\项目所需文件\工具\ffff\APL\Tool出力結果" output_excel = r"E:\system\Desktop\项目所需文件\工具\ffff\GA_D24D_00-00-01(三回目)_QAC.xlsx" winmerge_path = r"E:/App/WinMerge/WinMerge/WinMergeU.exe" print("="*50) print("开始文件比较...") try: # 修复变量名错误:new_dir -> new_code_dir changed_files = get_changed_files_and_lines(old_code_dir, new_code_dir, winmerge_path) print(f"找到 {len(changed_files)} 个变更文件") print("="*50) print("更新Excel表格...") success = update_excel_sheets(csv_folder, output_excel, changed_files) if success: print(f"处理完成! 输出文件: {output_excel}") else: print("处理失败,请检查错误日志") except Exception as e: print(f"处理过程中发生错误: {str(e)}") import traceback traceback.print_exc() print("="*50) print("程序结束") if __name__ == "__main__": main()
09-25
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值