首页/系统/Linux 运维命令速查/diff 比较文件与目录差异
文本处理77 条

diff 比较文件与目录差异

逐行找出两个文件(或目录)的不同:-u 统一格式生成补丁、-q 只报是否不同、-r 递归比目录,是配置巡检与发布核对的基本盘。

Linux 运维命令速查系统更新于 2026-10-13

diff 是什么

diff 逐行比较两个文件,输出把前者变成后者需要做的增删改;加上 -u 会输出统一格式(unified diff),这正是补丁与代码评审里看到的格式。它的价值不只是「看哪里不一样」,更在于把差异变成可复核、可传递、可回滚的文本:配置巡检、发布核对、变更审计都依赖它。比较目录时用 -r 递归,配合 -q 只看结论,就能在几分钟内确认两台机器的配置是否一致。

基本信息

适用平台Linux、macOS、BSD(GNU diffutils / BSD diff);--color、-y 并排输出等为 GNU 常见扩展
命令语法diff [选项] 文件1 文件2;比较目录时同样语法
常用选项-u 统一格式、-c 上下文格式、-q 只报告是否不同、-r 递归比较目录、-N 把缺失文件视为空文件、-w 忽略空白、-i 忽略大小写、-y 并排显示、--strip-trailing-cr 忽略行尾差异
退出码0 表示无差异、1 表示有差异、2 表示出错;这是 diff 在脚本中最常用的判断方式
相关工具cmp 做二进制逐字节比较、sha256sum 做整体校验、patch 应用差异、vimdiff 与 git diff 提供更友好的查看方式

典型使用场景

  • 配置巡检:比较当前配置与基线备份,确认是否被手工改动过
  • 发布核对:比较新旧版本目录,确认变更范围符合预期
  • 生成补丁:-u 输出可直接交给 patch 或进入代码评审流程
  • 快速判断是否相同:-q 配合退出码,适合在大批量文件上做筛查
  • 排查格式问题:先用 -w 忽略空白,若差异消失说明只是缩进或空格问题
  • 跨平台文件比对:用 --strip-trailing-cr 消除 Windows 与 Linux 行尾差异带来的假差异

常用示例

常用示例
diff app.conf app.conf.bak            # 普通格式
diff -u app.conf.old app.conf         # 统一格式(补丁用)
diff -q a.txt b.txt                   # 只报告是否不同
diff -r --brief /etc/app /data/app    # 目录递归、只看结论
diff -w a b                           # 忽略空白差异
diff -u old/ new/ > change.patch      # 生成补丁,可交给 patch 应用
diff -y --width=120 a b               # 并排显示,便于人工比对
diff --strip-trailing-cr win.txt linux.txt
if diff -q a b >/dev/null; then echo same; else echo differ; fi

差异标记读法

标记含义对应操作
a在第一个文件里新增内容才与第二个一致第一个文件缺少这些行
d删除第一个文件里的内容第一个文件多出这些行
c修改,第一个文件里的这段要换成新内容最常见的差异类型
< 开头来自第一个文件的行旧内容
> 开头来自第二个文件的行新内容
Only in 目录该目录独有的文件(比较目录时)用 -N 可把缺失视为空文件
先比整体再比细节是高效做法:两个文件的 sha256sum 相同就直接跳过,不同再用 cmp 找出首个差异位置(大文件上比逐行 diff 快得多),确认确实需要看内容差异时再用 diff。对目录做批量巡检时,先 diff -rq 拿到文件清单,再对重点关注的文件逐个细看。
常见假差异的成因:Windows 的 CRLF 与 Linux 的 LF、行尾多余空格、制表符与空格混用。对应处理是 --strip-trailing-cr、-w 与 -b(忽略空白数量变化)。排查「配置明明一样却不同」时,先加这些参数确认差异是否只是格式问题。
用 diff 生成的补丁应用到生产配置前,要在测试环境验证并保留原文件备份:路径前缀(-p 参数)与实际目录不一致会导致补丁修改错文件,部分应用也可能出现失败后留下半改状态的配置。

易错点

  • 超大文件直接 diff 很吃力:先用 cmp 或 sha256sum 判断是否相同,再决定是否需要逐行比较
  • 比较目录不带 -r 只会看到顶层差异,子目录里的改动全部漏掉;只看结论时用 -r --brief
  • 忽略 diff 的退出码语义(1 表示有差异而非出错),在脚本里把「有差异」当成命令失败处理
  • 跨平台文件不先统一行尾,满屏差异其实只是 CRLF 与 LF 的区别,白花时间排查
  • 把 diff 输出直接当补丁应用到生产配置而不做备份与验证,一旦路径或上下文不匹配可能改错文件

数据来源与参考

  • man 1 diff(GNU diffutils 手册)

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌