文本、JSON、Markdown 差异对比:三类工具怎么选、结果怎么读

同样是「比对两份文件」,文本要看行级增删、JSON 要按 key 对齐并把数组顺序影响降下来、Markdown 要按表格和标题结构看。选错工具的典型症状是:JSON 对比满屏都是改,因为它把数组重排当成了全部变化。

约 7 分钟读完 · 更新于 2026-10-21 · 文中每条都能在下面的配套工具里动手验证

先判断数据形状,再决定用哪个工具

三类常见数据的差异语义完全不同。纯文本和代码关心「哪几行变了」,行序本身就是信息;JSON 是键值结构,键的位置没有意义,同一份数据序列化后顺序不同也应视为相等;Markdown 介于两者之间——标题层级和表格结构有意义,但空行和缩进常常只是排版习惯。拿文本对比去做 JSON,会得到一份满屏「删一行、加一行」的噪声;拿 JSON 对比去做 Markdown,又会丢掉表格对齐这类真正想看的差异。

三类工具的行为对照

对比对象推荐工具对齐依据能忽略的噪音典型输出
纯文本 / 日志 / 代码text-diff行号,逐行一一对应行尾空白、大小写、忽略空行红绿高亮的增删块 + 统一 diff
JSON 接口返回 / 配置文件json-diffkey 路径,数组按 LCS 对齐对象键顺序、数组整体重排字段级增删改 + RFC 6902 Patch
Markdown 文档html-md 归一化后再对比标题与表格结构排版空行、缩进、列表缩进层级结构化差异视图
表格型数据(TSV/CSV)md-table + text-diff按单元格位置数字格式、千分位与精度差异Markdown 表格 + 差异标记
多份配置批量核对先文本统计再逐项对比key 名注释、字段顺序清单式不一致项
文本对比:真实场景输出形态
  12行  log.info("job start, id=1024");
- 13行  log.info("job done");
+ 13行  log.info("job done, cost=83ms");
  14行  log.info("exit 0");

统计:新增 1 行 / 删除 1 行 / 修改后总行数 14
JSON 对比:键顺序不同应判为「无差异」
A: {"a":1,"b":{"c":2,"d":3}}
B: {"b":{"d":3,"c":2},"a":1}

正确结果:无差异(键顺序不参与比较)
错误做法:先字符串化再逐行 diff → 会显示整块都被改写
数组重排:按 LCS 对齐 vs 按下标硬比
原数组:[{"id":1},{"id":2},{"id":3}]
新数组:[{"id":2},{"id":3},{"id":1}]

按 LCS 对齐:只有 1 项位置变化,读起来是「同一批数据换了顺序」
按下标硬比:3 项全部标记为「改」,噪音量放大三倍

文本对比:忽略规则比算法更影响结果

同两份文件,开关不同就是完全不同的结论。忽略大小写,适合比较 URL、SQL 关键字、环境变量名这类不区分大小写的场景;忽略全部空白,适合代码格式化后的一致性检查;忽略空行,适合 Markdown 里为了排版随手加的空行。真实冲突是:忽略空白之后,Python 里缩进有意义的代码会显示成「无差异」,但实际上行为完全不同。

JSON 对比:数组顺序到底算不算变化

这是 JSON 对比最容易出错的地方。数组在语义上有两种:有序的(比如流程步骤、路径)和无序的集合(比如标签、权限列表)。对有序数组,位置变化就是真实变化,必须显示;对无序集合,[a, b, c] 与 [c, a, b] 应当判定为相等。处理办法是给无序集合做键归一:按某个稳定字段(常见是 id)排序后再比,这样顺序噪音就消失了。LCS 对齐是折中方案,它不要求你先声明顺序语义,而是尽量把重排识别成「移动」而不是「删除 + 新增」,代价是输出里会同时出现减少和增加两种标记。

Markdown 对比:先归一化结构,再看差异

  1. 把 HTML 转成 Markdown,或反过来统一成同一种风格——不同工具导出的 Markdown 在空行、列表缩进、标题前后换行上习惯不同,直接比会满屏噪音。
  2. 重点看标题层级:# 的层级跳变(从 ## 直接到 ####)通常意味着结构被改过,比正文改动更值得注意。
  3. 表格要按单元格比,不能按行比:把表格转成 Markdown 表格后再逐行对比,某一列改动就能定位到具体格子。
  4. 链接和图片路径单独扫一遍:正文只改了一个图片地址,文本 diff 可能只显示一行变化,扫路径更容易发现。
  5. 代码块内部只做逐字对比,不要试图忽略空白——示例代码里的缩进常常是刻意为之。

对比结果的三个常见误读

  • 「变化行数少就说明改得少」:一个字符的改动可能让整段格式化后的内容全变。判断改动量要看语义,不是看 diff 的行数。
  • 「没有差异就说明两份等价」:忽略大小写、忽略空白这些开关打开时,「无差异」只在你设定的规则下成立,不代表内容真的相同。
  • 「差异越少工具越差」:工具做了语义对齐(数组按 LCS 对齐、键顺序归一)之后,差异行变少恰恰说明它更懂结构;噪音才是差工具的标志。

一条能落地的对比流程:从数据形状到结论

拿到两份不知道该用什么工具的内容时,按这四步走一遍基本不会错。第一步先看数据形状:有嵌套对象和数组就是 JSON,顶部是 # 标题就是 Markdown,剩下的按行看。第一步的输出决定第二步用什么工具:JSON 交给按 key 路径比较的那类,Markdown 先转成统一风格再比,纯文本直接逐行比。第二步是设定噪音规则,规则要显式写出来——「忽略空白后无差异」和「无差异」是两句话,报告给别人时必须带上规则,否则对方无法判断结论的适用范围。第三步在对比前先做一次体检:用文本统计看两侧的行数、字符数、行尾符和是否带 BOM,如果两边体量差一个数量级,先搞清楚是不是拿错了文件,而不是急着逐行看差异。第四步才是读结果,且要先看统计再看细节:先确认「多了几行、删了几处」,再定位到具体位置,顺序反过来容易被第一处无关差异带偏。

常见问题

JSON 对比显示的差异太多了,是不是工具有问题?

很可能是数组顺序造成的。默认按数组下标逐个比较时,一个元素挪位就会让整段都标成「改」。换一个带 LCS 对齐或支持按 id 排序比较的 JSON 对比工具,差异会收敛到真正的字段变化上。

怎么比较两份 JSON 而忽略键的顺序?

关键是别把 JSON 先压成字符串再逐行比。JSON 对象在语义上无序,用按 key 路径递归比较的对比工具,键顺序不同会判为无差异;先用 JSON 格式化工具规范化也不会解决重排,只是把噪音变得整齐而已。

文本对比时忽略空白安全吗?

取决于内容。对 URL、SQL、日志这类空白不敏感的场景很安全;对 Python、YAML 这类缩进有意义的语言则很危险,缩进变了行为就变了,忽略空白会把真实的错误判成无差异。

对比两个 Markdown 表格文件,怎么快速看出改了哪个格子?

先用 Markdown 表格生成器把内容对齐成规范表格(补齐分隔行、统一列数),再对这两份规范化结果做逐行对比,差异就会精确落到行和列上。直接对比原始文本会被排版空格干扰。

📂

松开以自动格式化

支持 .json / .sql / .csv / .html / .css / .xml / .yaml 文件