← 返回 Skills 市场
534422530

文本对比工具

作者 534422530 · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ✓ 安全检测通过
40
总下载
0
收藏
0
当前安装
1
版本数
在 OpenClaw 中安装
/install laosi-text-diff
功能描述
文本对比 - 对比两段文本差异,逐行diff,高亮变更,支持side-by-side和unified格式输出
使用说明 (SKILL.md)

Text Diff - 文本对比工具

激活词: 对比 / diff / 比较文本 / 找不同

功能

  • 逐行文本对比 (unified diff)
  • 高亮新增/删除/修改行
  • Side-by-side视图
  • 文件对比
  • 统计变更信息
  • 忽略空白差异

Python 实现

import difflib, json, os
from datetime import datetime
from typing import List, Tuple, Dict

class TextDiff:
    def __init__(self):
        self.results: list = []
    
    def diff(self, old_text: str, new_text: str, context: int = 3) -> dict:
        """对比两段文本"""
        old_lines = old_text.splitlines(keepends=True)
        new_lines = new_text.splitlines(keepends=True)
        
        # Unified diff
        unified = list(difflib.unified_diff(
            old_lines, new_lines,
            fromfile="old", tofile="new",
            lineterm="", n=context
        ))
        
        # 计算统计
        added = [l[1:].rstrip() for l in unified if l.startswith("+") and not l.startswith("+++")]
        removed = [l[1:].rstrip() for l in unified if l.startswith("-") and not l.startswith("---")]
        
        # Side-by-side
        sbs = list(difflib.ndiff(old_lines, new_lines))
        left = [l[2:].rstrip() for l in sbs if l.startswith("- ") or l.startswith("  ")]
        right = [l[2:].rstrip() for l in sbs if l.startswith("+ ") or l.startswith("  ")]
        
        result = {
            "unified": "".join(unified),
            "side_by_side": {"old": left, "new": right},
            "stats": {
                "old_lines": len(old_lines),
                "new_lines": len(new_lines),
                "added": len(added),
                "removed": len(removed),
                "changed": max(len(added), len(removed)),
                "similarity": self._similarity(old_lines, new_lines),
            },
            "added_lines": added,
            "removed_lines": removed,
            "timestamp": datetime.now().isoformat(),
        }
        self.results.append(result)
        return result
    
    def diff_files(self, old_path: str, new_path: str) -> dict:
        """对比两个文件"""
        with open(old_path, encoding="utf-8") as f:
            old = f.read()
        with open(new_path, encoding="utf-8") as f:
            new = f.read()
        
        result = self.diff(old, new)
        result["old_file"] = old_path
        result["new_file"] = new_path
        return result
    
    def _similarity(self, old: list, new: list) -> float:
        """计算相似度百分比"""
        sm = difflib.SequenceMatcher(None, old, new)
        return round(sm.ratio() * 100, 1)
    
    def ignore_whitespace(self, old_text: str, new_text: str) -> dict:
        """忽略空白差异的对比"""
        import re
        def normalize(text):
            return re.sub(r'\s+', ' ', text).strip()
        old_norm = "\
".join(normalize(l) for l in old_text.splitlines())
        new_norm = "\
".join(normalize(l) for l in new_text.splitlines())
        return self.diff(old_norm, new_norm)
    
    def print_side_by_side(self, old_text: str, new_text: str, width: int = 80):
        """并排显示差异"""
        old_lines = old_text.splitlines()
        new_lines = new_text.splitlines()
        sm = difflib.SequenceMatcher(None, old_lines, new_lines)
        
        half = width // 2 - 2
        print(f"{'OLD':^{half}} | {'NEW':^{half}}")
        print("-" * width)
        
        for tag, i1, i2, j1, j2 in sm.get_opcodes():
            if tag == "equal":
                for line in old_lines[i1:i2]:
                    print(f"{line[:half]:>{half}} | {line[:half]:\x3C{half}}")
            elif tag == "replace":
                for old, new in zip(old_lines[i1:i2], new_lines[j1:j2]):
                    print(f"{old[:half]:>{half}} | {new[:half]:\x3C{half}}")
            elif tag == "delete":
                for line in old_lines[i1:i2]:
                    print(f"{line[:half]:>{half}} | {'':{half}}")
            elif tag == "insert":
                for line in new_lines[j1:j2]:
                    print(f"{'':{half}} | {line[:half]:\x3C{half}}")

# 使用示例
differ = TextDiff()

# 简单对比
old = """def hello():
    print("Hello, World!")
    return True"""

new = """def hello(name: str):
    print(f"Hello, {name}!")
    return True
    # Added comment"""

result = differ.diff(old, new)
print(f"统计: +{result['stats']['added']} -{result['stats']['removed']} (相似度: {result['stats']['similarity']}%)")
print(f"\
Unified Diff:")
print(result["unified"])

# 并排显示
print("\
Side-by-Side:")
differ.print_side_by_side(old, new, width=60)

# 文件对比
# result = differ.diff_files("v1.py", "v2.py")

输出格式

统计: +3 -2 (相似度: 85.7%)

--- old
+++ new
@@ -1,3 +1,4 @@
 def hello():
-    print("Hello, World!")
+    print(f"Hello, {name}!")
     return True
+    # Added comment

使用场景

  1. 代码审查: 比较PR前后代码差异
  2. 配置管理: 检查配置文件变更
  3. 文档更新: 对比文档修订内容
  4. 调试: 找出程序输出的差异

依赖

  • Python 3.8+
  • 标准库(difflib)
安全使用建议
Installers should be aware that generic words like diff or compare may invoke the skill unexpectedly. Use it for text or files you intend to compare, since diff output can reveal the contents of those inputs in the chat.
能力评估
Purpose & Capability
The stated purpose is text diffing, and the artifact implements that with Python standard-library comparison functions plus optional file reads for user-specified paths.
Instruction Scope
The activation phrases are broad enough that the skill may be invoked accidentally, but the instructions remain limited to comparison output and do not request unrelated authority.
Install Mechanism
The package contains a single non-executable SKILL.md file, declares no external dependencies, and has clean static and dependency scan context.
Credentials
Environment access is proportionate to the purpose: it can compare provided text or read two explicitly named files, with no network calls or broad indexing behavior.
Persistence & Privilege
The sample code stores results only in memory during runtime and does not create persistence, escalate privileges, install packages, or modify files.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install laosi-text-diff
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /laosi-text-diff 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.0
Initial release of text-diff: - Provides line-by-line text comparison in unified and side-by-side formats - Highlights added, removed, and modified lines - Supports file-to-file diff and change statistics - Includes option to ignore whitespace differences - Built with Python 3.8+ using only standard library (difflib)
元数据
Slug laosi-text-diff
版本 1.0.0
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 1
常见问题

文本对比工具 是什么?

文本对比 - 对比两段文本差异,逐行diff,高亮变更,支持side-by-side和unified格式输出. 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 40 次。

如何安装 文本对比工具?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install laosi-text-diff」即可一键安装,无需额外配置。

文本对比工具 是免费的吗?

是的,文本对比工具 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

文本对比工具 支持哪些平台?

文本对比工具 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 文本对比工具?

由 534422530(@534422530)开发并维护,当前版本 v1.0.0。

💬 留言讨论