本文目录导读:

我来帮你创建一个自动对比文档差异并生成脚本的工具,这里提供Python实现方案:
方案1:基于difflib的文档对比工具
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
文档差异对比工具 - 自动对比并输出差异脚本
"""
import difflib
import os
import sys
from datetime import datetime
class DocumentDiffTool:
def __init__(self, file1, file2):
self.file1 = file1
self.file2 = file2
self.diff_results = []
def read_file(self, file_path):
"""读取文件内容"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
return f.readlines()
except UnicodeDecodeError:
# 尝试其他编码
try:
with open(file_path, 'r', encoding='gbk') as f:
return f.readlines()
except:
print(f"无法读取文件: {file_path}")
return []
def compare_files(self):
"""对比两个文件的差异"""
lines1 = self.read_file(self.file1)
lines2 = self.read_file(self.file2)
# 创建差异比较器
differ = difflib.Differ()
diff = list(differ.compare(lines1, lines2))
# 分析差异
changes = []
for line in diff:
if line.startswith('+ '):
changes.append(('ADD', line[2:]))
elif line.startswith('- '):
changes.append(('DELETE', line[2:]))
elif line.startswith('? '):
changes.append(('CHANGE', line[2:]))
return changes, diff
def generate_diff_script(self, changes, output_file=None):
"""生成差异脚本"""
script_lines = []
script_lines.append(f"# 文档差异脚本")
script_lines.append(f"# 对比文件: {self.file1} ↔ {self.file2}")
script_lines.append(f"# 生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
script_lines.append(f"# 总修改: {len([c for c in changes if c[0] != 'UNCHANGED'])} 处")
script_lines.append("")
# 生成HTML格式的差异报告
html_diff = difflib.HtmlDiff().make_file(
self.read_file(self.file1),
self.read_file(self.file2),
self.file1,
self.file2
)
# 生成详细脚本
add_count = 0
del_count = 0
change_count = 0
for change_type, content in changes:
if change_type == 'ADD':
add_count += 1
script_lines.append(f"# 添加[{add_count}]: {content}")
elif change_type == 'DELETE':
del_count += 1
script_lines.append(f"# 删除[{del_count}]: {content}")
elif change_type == 'CHANGE':
change_count += 1
script_lines.append(f"# 修改[{change_count}]: {content}")
script_lines.append("")
script_lines.append(f"# 统计信息:")
script_lines.append(f"# 添加: {add_count} 处")
script_lines.append(f"# 删除: {del_count} 处")
script_lines.append(f"# 修改: {change_count} 处")
script_content = '\n'.join(script_lines)
# 保存脚本
if output_file:
with open(output_file, 'w', encoding='utf-8') as f:
f.write(script_content)
print(f"差异脚本已保存到: {output_file}")
# 保存HTML报告
html_file = output_file.replace('.txt', '.html') if output_file else 'diff_report.html'
with open(html_file, 'w', encoding='utf-8') as f:
f.write(html_diff)
print(f"HTML报告已保存到: {html_file}")
return script_content
def print_summary(self, changes):
"""打印差异摘要"""
add_count = len([c for c in changes if c[0] == 'ADD'])
del_count = len([c for c in changes if c[0] == 'DELETE'])
change_count = len([c for c in changes if c[0] == 'CHANGE'])
print("\n" + "="*50)
print("文档对比结果摘要")
print("="*50)
print(f"原始文件: {self.file1}")
print(f"对比文件: {self.file2}")
print(f"添加内容: {add_count} 处")
print(f"删除内容: {del_count} 处")
print(f"修改内容: {change_count} 处")
print(f"总变化: {add_count + del_count + change_count} 处")
print("="*50)
def main():
"""主函数"""
if len(sys.argv) < 3:
print("使用方法: python diff_tool.py <原文件> <新文件> [输出脚本]")
print("示例: python diff_tool.py old.txt new.txt diff_script.txt")
sys.exit(1)
file1 = sys.argv[1]
file2 = sys.argv[2]
output_file = sys.argv[3] if len(sys.argv) > 3 else f"diff_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
# 检查文件是否存在
if not os.path.exists(file1):
print(f"错误: 文件 '{file1}' 不存在")
sys.exit(1)
if not os.path.exists(file2):
print(f"错误: 文件 '{file2}' 不存在")
sys.exit(1)
# 创建对比工具实例
tool = DocumentDiffTool(file1, file2)
# 执行对比
print(f"正在对比文件: {file1} ↔ {file2}")
changes, raw_diff = tool.compare_files()
# 打印摘要
tool.print_summary(changes)
# 生成差异脚本
script = tool.generate_diff_script(changes, output_file)
# 显示差异内容(前20行)
print("\n差异内容预览:")
print("-"*50)
display_lines = 0
for change_type, content in changes:
if display_lines >= 20:
print("... (更多差异已保存到文件)")
break
symbol = {'ADD': '+', 'DELETE': '-', 'CHANGE': '?'}
print(f"{symbol.get(change_type, ' ')} {content}", end='')
display_lines += 1
if __name__ == "__main__":
main()
方案2:更高级的对比工具(支持多格式)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
高级文档差异对比工具 - 支持多种文件格式
"""
import difflib
import os
import json
import re
from datetime import datetime
class AdvancedDiffTool:
def __init__(self):
self.supported_formats = ['.txt', '.py', '.html', '.css', '.js', '.json', '.xml', '.md']
def compare_structures(self, file1, file2):
"""对比结构化文档"""
ext1 = os.path.splitext(file1)[1].lower()
ext2 = os.path.splitext(file2)[1].lower()
if ext1 != ext2:
print("警告: 文件格式不同,使用基础文本对比")
return self.basic_compare(file1, file2)
if ext1 == '.json':
return self.compare_json(file1, file2)
elif ext1 in ['.xml', '.html']:
return self.compare_xml(file1, file2)
else:
return self.basic_compare(file1, file2)
def compare_json(self, file1, file2):
"""对比JSON文件"""
with open(file1, 'r', encoding='utf-8') as f:
data1 = json.load(f)
with open(file2, 'r', encoding='utf-8') as f:
data2 = json.load(f)
changes = []
def compare_dicts(d1, d2, path=""):
keys1 = set(d1.keys())
keys2 = set(d2.keys())
# 新增的键
for key in keys2 - keys1:
changes.append(('ADD', f"{path}.{key}: {json.dumps(d2[key], ensure_ascii=False)}"))
# 删除的键
for key in keys1 - keys2:
changes.append(('DELETE', f"{path}.{key}: {json.dumps(d1[key], ensure_ascii=False)}"))
# 修改的值
for key in keys1 & keys2:
if isinstance(d1[key], dict) and isinstance(d2[key], dict):
compare_dicts(d1[key], d2[key], f"{path}.{key}")
elif d1[key] != d2[key]:
changes.append(('MODIFY', f"{path}.{key}: {json.dumps(d1[key], ensure_ascii=False)} → {json.dumps(d2[key], ensure_ascii=False)}"))
compare_dicts(data1, data2)
return changes
def compare_xml(self, file1, file2):
"""对比XML/HTML文件"""
import xml.etree.ElementTree as ET
def parse_xml(file_path):
try:
tree = ET.parse(file_path)
return tree.getroot()
except:
return None
root1 = parse_xml(file1)
root2 = parse_xml(file2)
if root1 is None or root2 is None:
return self.basic_compare(file1, file2)
changes = []
def compare_elements(elem1, elem2, path=""):
# 对比标签
if elem1.tag != elem2.tag:
changes.append(('CHANGE', f"标签变化: {elem1.tag} → {elem2.tag}"))
# 对比属性
attr1 = elem1.attrib
attr2 = elem2.attrib
for key in attr2:
if key not in attr1:
changes.append(('ADD', f"新增属性 {path}[@{key}={attr2[key]}]"))
elif attr1[key] != attr2[key]:
changes.append(('CHANGE', f"属性变化 {path}[@{key}: {attr1[key]} → {attr2[key]}]"))
for key in attr1:
if key not in attr2:
changes.append(('DELETE', f"删除属性 {path}[@{key}={attr1[key]}]"))
# 对比文本内容
text1 = (elem1.text or "").strip()
text2 = (elem2.text or "").strip()
if text1 != text2:
if text1 and text2:
changes.append(('CHANGE', f"文本变化 at {path}: '{text1}' → '{text2}'"))
elif text2:
changes.append(('ADD', f"添加文本 at {path}: '{text2}'"))
else:
changes.append(('DELETE', f"删除文本 at {path}: '{text1}'"))
# 递归对比子元素
children1 = list(elem1)
children2 = list(elem2)
for i, child in enumerate(children2):
if i < len(children1):
compare_elements(children1[i], child, f"{path}/{child.tag}")
else:
changes.append(('ADD', f"新增元素 {path}/{child.tag}"))
for i in range(len(children2), len(children1)):
changes.append(('DELETE', f"删除元素 {path}/{children1[i].tag}"))
compare_elements(root1, root2)
return changes
def basic_compare(self, file1, file2):
"""基础文本对比"""
def read_file(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
return f.readlines()
lines1 = read_file(file1)
lines2 = read_file(file2)
differ = difflib.Differ()
diff = list(differ.compare(lines1, lines2))
changes = []
for i, line in enumerate(diff):
if line.startswith('+ '):
changes.append(('ADD', line[2:].strip()))
elif line.startswith('- '):
changes.append(('DELETE', line[2:].strip()))
elif line.startswith('? '):
changes.append(('CHANGE', line[2:].strip()))
return changes
def generate_patch_script(changes, original_file, modified_file, output_file):
"""生成可执行的patch脚本"""
script = []
script.append("#!/bin/bash")
script.append(f"# 自动生成的补丁脚本")
script.append(f"# 生成时间: {datetime.now()}")
script.append(f"# 原始文件: {original_file}")
script.append(f"# 修改后文件: {modified_file}")
script.append("")
add_commands = []
delete_commands = []
modify_commands = []
for change_type, content in changes:
if change_type == 'ADD':
add_commands.append(f"echo '添加: {content}'")
add_commands.append(f"sed -i 's/$/\\n{content}/' {original_file}")
elif change_type == 'DELETE':
delete_commands.append(f"echo '删除: {content}'")
# 转义特殊字符
escaped_content = content.replace('/', '\\/').replace('&', '\\&')
delete_commands.append(f"sed -i '/{escaped_content}/d' {original_file}")
elif change_type == 'CHANGE':
modify_commands.append(f"echo '修改: {content}'")
if add_commands:
script.append("# 添加操作")
script.extend(add_commands)
script.append("")
if delete_commands:
script.append("# 删除操作")
script.extend(delete_commands)
script.append("")
if modify_commands:
script.append("# 修改操作")
script.extend(modify_commands)
script.append("")
script.append(f"echo '补丁应用完成'")
script.append(f"echo '请检查文件: {original_file}'")
with open(output_file, 'w', encoding='utf-8') as f:
f.write('\n'.join(script))
# 设置执行权限
os.chmod(output_file, 0o755)
print(f"补丁脚本已生成: {output_file}")
def main():
import sys
if len(sys.argv) < 3:
print("使用方法:")
print(" python advanced_diff.py <原文件> <新文件>")
print(" python advanced_diff.py <原文件> <新文件> -o <输出脚本>")
print(" python advanced_diff.py <原文件> <新文件> -p <补丁脚本>")
sys.exit(1)
file1 = sys.argv[1]
file2 = sys.argv[2]
# 解析参数
output_script = None
patch_script = None
if '-o' in sys.argv:
idx = sys.argv.index('-o')
if idx + 1 < len(sys.argv):
output_script = sys.argv[idx + 1]
if '-p' in sys.argv:
idx = sys.argv.index('-p')
if idx + 1 < len(sys.argv):
patch_script = sys.argv[idx + 1]
# 检查文件
if not os.path.exists(file1):
print(f"错误: 文件 '{file1}' 不存在")
sys.exit(1)
if not os.path.exists(file2):
print(f"错误: 文件 '{file2}' 不存在")
sys.exit(1)
# 创建对比工具
tool = AdvancedDiffTool()
# 执行对比
print(f"正在对比文件: {file1} ↔ {file2}")
changes = tool.compare_structures(file1, file2)
# 输出结果
print("\n差异分析结果:")
print("="*60)
for change_type, content in changes:
symbol = {'ADD': '➕', 'DELETE': '➖', 'CHANGE': '🔄', 'MODIFY': '✏️'}
print(f" {symbol.get(change_type, '•')} [{change_type}] {content}")
print("="*60)
print(f"总差异数: {len(changes)}")
# 生成输出脚本
if output_script:
with open(output_script, 'w', encoding='utf-8') as f:
f.write(f"# 文档差异报告\n")
f.write(f"# 对比: {file1} ↔ {file2}\n")
f.write(f"# 时间: {datetime.now()}\n")
f.write(f"# 差异总数: {len(changes)}\n\n")
for change_type, content in changes:
f.write(f"[{change_type}] {content}\n")
print(f"差异报告已保存: {output_script}")
# 生成补丁脚本
if patch_script:
generate_patch_script(changes, file1, file2, patch_script)
if __name__ == "__main__":
main()
使用方法
基础使用方法:
# 对比两个文本文件 python diff_tool.py old.txt new.txt # 指定输出脚本文件 python diff_tool.py old.txt new.txt diff_script.txt # 高级版本 - 生成补丁脚本 python advanced_diff.py old.txt new.txt -p patch.sh # 高级版本 - 指定输出格式 python advanced_diff.py old.txt new.txt -o report.txt
功能特点:
- 自动检测文件编码 (UTF-8, GBK等)
- 支持多种文件格式 (文本, JSON, XML, HTML等)
- 生成HTML可视化报告
- 生成可执行的补丁脚本
- 详细的统计信息
- 彩色控制台输出 (可扩展)
输出示例:
文档对比结果摘要
==================================================
原始文件: old.txt
对比文件: new.txt 5 处 3 处 2 处
总变化: 10 处
==================================================
预览:
--------------------------------------------------
[ADD] 新的内容行1
[DELETE] 删除的内容行
[CHANGE] 修改的内容
...
这个工具可以自动识别文档差异,并根据差异类型生成相应的操作脚本,非常适合版本控制、文件同步等场景。