先分流:你比的是什么
「找出两段文本哪里不一样」这个需求,输入长什么样决定了正确做法:
| 你要比的 | 正确姿势 | 为什么 |
|---|---|---|
| 两版配置、两段日志、两版代码/文档 | 直接贴进文本对比工具(如本站 文本差异对比器) | 顺序就是语义,逐行 diff 正是对的工具 |
| 两份顺序无关的清单(依赖列表、词表、文件名) | 先各自行排序,再对比 | 顺序差异会淹没成员差异,排序后剩下的全是真实增删 |
| 两份 JSON | 别用文本 diff,用 JSON 对比 | 键序/空白/转义制造海量假差异,结构化对比按字段路径报告 |
| git 工作区里的改动 | git diff |
版本系统本来就懂「谁改的、什么时候改的」,浏览器工具是给它善后的 |
前两行的细节是本文的正题:视图怎么读、假差异怎么消。
diff 视图怎么读
对比结果有两种呈现,各有领地:
- 分栏视图(split):左原文右改文,同一行号左右对齐,改动行高亮。适合「对照着读」——看清楚每处改动的前后状态,宽屏下效率最高;
- 统一视图(unified):删行带
-前缀、增行带+前缀,从上往下线性读。适合逐行审阅、窄屏,以及把结果复制给别人——它的形态接近git diff与diff -u的输出,任何看惯代码评审的人都秒懂。
常见节奏是先分栏定位(左右对照快速扫出改动簇),再切统一视图复查细节。增删行数统计是第一个该看的数字:它告诉你改动面有多大,决定你用「逐行读」还是「抽样读」。
三类假差异怎么消
逐行对比的原理是「字符串相等的行才算相同」,所以任何与语义无关的字面差异都会被标红。三类最常见:
空白与大小写噪音:缩进调整、行尾空格、大小写变化(配置里 true 与 True)。开「忽略空白」「忽略大小写」选项——但要清楚代价:开着它们也可能掩盖真实改动(把 DEBUG=true 改成 debug=true 的人会漏网)。先关选项看严格结果,噪音太多再开,是稳妥顺序。
行尾符(CRLF vs LF):Windows 保存的文件是 CRLF,Unix 是 LF,逐行对比里它们是不同的行——一份文件只是换了个编辑器打开保存,就全篇标红。这是「明明没改却满屏红」的头号原因,先统一行尾(工具的文本调整菜单有一键统一)再比。
特殊字符与不可见字符:零宽空格、BOM、装饰性符号——肉眼看不出但让行不相等,「忽略特殊字符」选项把标点符号类字符从比对中剔除,恰好也压掉零宽字符这类隐形噪音。怀疑有不可见字符时,观察「明明看起来一样的行被标红」就是信号。
整理后再比:两个高频招
无序清单先排序:对比两份依赖列表、两份词表时,顺序差异会让 diff 结果全是噪音。先用行排序把两份各自按字典序排好,再对比——剩下的差异全是成员级的增删,一眼看清谁多了谁少了。判断标准就一句话:这份清单的顺序本身是不是信息?不是,就排。
被格式化过的文本先归一:两边各自被不同的编辑器格式化过(缩进、换行风格不同)时,diff 报告的是格式差异而非内容差异。把两份用同一规则整理(统一行尾、统一缩进策略)再比。JSON 特殊一些:格式化/压缩的辅助按钮可以临时救急,但正解是结构化对比——那不是文本 diff 该扛的活。
真话:边界在哪里
- 50 万字符/侧的上限:日志全量、数据转储这类超长文本,浏览器不是正确的战场,命令行
diff -u a.txt b.txt没有这个限制,输出还能进管道; - 超过 2 份文本的对比:三方合并是 git 的领地,两两对比的网页工具做不了 merge 语义;
- 版本历史与「谁改的」:文本 diff 只回答「哪里不同」,不回答「什么时候、谁、为什么改的」——这些在版本系统里。网页工具的最强场景是手里只有两段文本、没有版本库的时候:聊天里贴来的两段配置、别人发来的两版文档、线上环境与本地环境的输出对照。
常见问题
为什么明明只改了一行,diff 结果标了一大片?
三个常见原因:一是行尾符不同——Windows 的 CRLF 与 Unix 的 LF 在逐行对比里是不同的行,一份文件换了个编辑器保存就全篇标红,先统一行尾再比;二是空白差异——缩进变化、行尾空格让行不相等,开「忽略空白」;三是文本被整体格式化过(重排、重新缩进),此时 diff 结果是真实但无用——先把两份用同一规则格式化,再比。
怎么对比两份顺序不同的清单?
先用工具的行排序把两份清单各自按字典序排好,再对比——顺序无关的清单(依赖列表、词表、文件清单)直接比会被顺序差异淹没,排序后剩下的差异全是成员级的增删。判断标准想清楚一件事:这份清单的顺序本身是不是信息?是(如优先级列表)就不能排,不是(如依赖集合)就排。
分栏视图和统一视图各适合什么时候用?
分栏(split)适合较宽的屏幕和「左右对照着读」的场景——看同一处改动的前后状态;统一(unified)适合逐行顺序审阅、窄屏、以及把结果贴给别人(统一视图的线性结构接近 git diff 的输出,沟通成本低)。同一个差异结果两种视图零成本切换,先分栏定位、再统一复查是常见节奏。
文本 diff 能比两份 JSON 吗?
能贴进去比,但不该:JSON 的键序、空白、转义写法会让文本 diff 报出海量假差异,而且一个值的改动会把整行标红、定位不到具体字段。比 JSON 用结构化对比——按 JSONPath 报告哪个字段增删改,键序默认忽略。文本 diff 的领地是配置、日志、代码、文档这类「行本身就是语义单元」的内容。