diff 用于比较文本文件或目录:单文件优先用 -u 提高可读性,目录必须加 -r 才递归;默认输出(如 3c3、)简略难懂,且对二进制文件静默跳过;-u 格式以 ---(第一参数)和 +++(第二参数)标识源/目标,并用上下文精准定位变更。

直接说结论:用 diff 比较文件,优先加 -u;比较目录,必须加 -r,再根据需求叠加 -q 或 -y —— 不加这些,输出要么难读,要么漏内容。
为什么 diff file1 file2 有时没输出,有时又全是符号?
没输出 ≠ 文件相同,可能是二进制文件(diff 默认跳过)或权限不足;全是一堆 1c1、、<code>> 是默认简略格式,对人不友好。
- 确认是否为文本文件:
file file1,若显示data或executable,需加-a强制当文本处理 - 默认格式中,
3c3表示“第3行要改”,是源文件内容,<code>>是目标文件内容 —— 这个顺序取决于你写的参数顺序:diff a b以a为基准,b为目标 - 想一眼看出改了啥,别用默认格式,直接上
diff -u file1 file2
diff -u 输出里 --- 和 +++ 到底哪边是“原文件”?
--- 对应第一个参数(源),+++ 对应第二个参数(目标),但注意:这个“源/目标”只是标记名,diff 本身不修改任何文件,也不预设谁该向谁看齐。
-
@@ -1,3 +1,4 @@中的-1,3表示“从源文件第1行开始取3行”,+1,4表示“目标文件对应位置取4行” - 删掉的行前面是
-,新增的是+,没变的上下文行(默认3行)前面没符号 —— 这就是为什么-u适合生成补丁:patch能靠上下文准确定位 - 如果上下文太少导致定位失败(比如两处改动只隔1行),可加大上下文行数:
diff -U5 file1 file2
比较目录时 diff -r dir1 dir2 为什么列出一堆“Only in”却不说哪里不同?
因为 -r 只递归找同名文件并逐个比较,遇到只在一边存在的文件,就直接报 Only in dir1: foo.txt,不会尝试 diff 一个文件和“不存在”。
- 想快速知道哪些文件内容不同(忽略新增/缺失),加
-q:diff -rq dir1 dir2 - 想看到具体哪几行不同,得让
diff对每个同名文件都跑一次-u,但默认不这么做 —— 所以实际建议组合:diff -ru dir1 dir2(-r+-u) - 注意
-N参数:它会让diff把只在一边存在的文件,当成“和空文件比较”,从而输出类似diff -u /dev/null missing.txt的补丁式结果 —— 仅在需要完整补丁流时用,日常排查反而干扰判断
用 diff -y 并排对比时,为什么有些行标了 | 却没标 /<code>>?
-y 模式下,| 表示左右内容不同但行数对齐; 表示左有右无;<code>> 表示右有左无 —— 它不保证左右绝对按原始行号对齐,而是尽量做“语义对齐”。
- 如果某行左边是空、右边是内容,可能显示为
> content,而不是| content - 列宽默认130字符,超长会被截断,可用
-W 200加宽;加--suppress-common-lines可隐藏完全相同的行,聚焦差异 -
-y在终端里看着直观,但无法用于生成补丁(patch不认这种格式),也难用脚本解析 —— 别拿它做自动化判断
真正容易被忽略的点是:目录比较时,diff 默认不进入子目录中的符号链接指向的目标,除非加 --no-dereference 显式禁止跟随 —— 如果你发现两个看似结构一致的目录被报告大量“Only in”,先检查有没有软链混在里面。











