diff命令

diff命令 #

diff命令用于比较文件之间的差异,并以行为单位显示不同之处。它是一个强大的工具,可以帮助用户识别文件之间的变化,常用于比较代码、配置文件或文本文档的不同版本。

语法 #

diff [选项] 文件1 文件2

常用选项 #

选项 描述
-b, --ignore-space-change 忽略空白数量的变化
-B, --ignore-blank-lines 忽略空行的变化
-i, --ignore-case 忽略大小写差异
-w, --ignore-all-space 忽略所有空白
-y, --side-by-side 以并排格式输出
-u, --unified[=NUM] 以统一格式输出,显示NUM行上下文(默认为3)
-c, --context[=NUM] 以上下文格式输出,显示NUM行上下文(默认为3)
-N, --new-file 将不存在的文件视为空文件
-a, --text 将所有文件视为文本文件
-r, --recursive 递归比较目录中的文件
-q, --brief 只报告文件是否不同
--normal 以正常格式输出(默认)
--color[=WHEN] 使用颜色标记输出(WHEN可以是’never’、‘always’或’auto’)
-d, --minimal 尝试找出最小的差异集
-p, --show-c-function 显示包含差异的C函数
-F, --show-function-line=RE 显示匹配RE的最近一行
-l, --paginate 通过’pr’传递输出以分页
-t, --expand-tabs 在输出中扩展制表符为空格
-T, --initial-tab 使制表符对齐
--suppress-common-lines 不输出相同的行
--help 显示帮助信息
--version 显示版本信息

输出格式 #

diff命令有几种不同的输出格式:

1. 正常格式(默认) #

n1a n2,n3
> 行内容
...

n4,n5c n6,n7
< 行内容
...
---
> 行内容
...

n8,n9d n10
< 行内容
...

其中:

  • n1a n2,n3:在文件1的第n1行后添加文件2的第n2到n3行
  • n4,n5c n6,n7:将文件1的第n4到n5行更改为文件2的第n6到n7行
  • n8,n9d n10:删除文件1的第n8到n9行(在文件2的第n10行之前)
  • <:表示来自文件1的行
  • >:表示来自文件2的行
  • ---:分隔更改的行

2. 上下文格式(-c) #

*** 文件1    时间戳
--- 文件2    时间戳
***************
*** n1,n2 ****
  行内容
! 更改的行
  行内容
--- n3,n4 ----
  行内容
! 更改的行
  行内容

其中:

  • ***:表示来自文件1的行
  • ---:表示来自文件2的行
  • 空格:两个文件中相同的行
  • !:更改的行
  • +:添加的行(只在文件2中存在)
  • -:删除的行(只在文件1中存在)

3. 统一格式(-u) #

--- 文件1    时间戳
+++ 文件2    时间戳
@@ -n1,n2 +n3,n4 @@
 行内容
-删除的行
+添加的行
 行内容

其中:

  • -n1,n2:文件1中从第n1行开始的n2行
  • +n3,n4:文件2中从第n3行开始的n4行
  • 空格:两个文件中相同的行
  • -:只在文件1中存在的行(被删除)
  • +:只在文件2中存在的行(被添加)

4. 并排格式(-y) #

行内容                      行内容
删除的行                  <
                        >  添加的行
更改的行                 |  更改的行
行内容                      行内容

其中:

  • 空格:两个文件中相同的行
  • <:只在文件1中存在的行
  • >:只在文件2中存在的行
  • |:两个文件中不同的行

常见用法 #

1. 比较两个文件 #

diff file1.txt file2.txt

2. 以统一格式显示差异 #

diff -u file1.txt file2.txt

3. 以上下文格式显示差异 #

diff -c file1.txt file2.txt

4. 并排比较两个文件 #

diff -y file1.txt file2.txt

5. 忽略空白差异 #

diff -w file1.txt file2.txt

6. 忽略大小写差异 #

diff -i file1.txt file2.txt

7. 忽略空行 #

diff -B file1.txt file2.txt

8. 递归比较两个目录 #

diff -r dir1 dir2

9. 只报告文件是否不同 #

diff -q file1.txt file2.txt

10. 使用颜色标记差异 #

diff --color=always file1.txt file2.txt

11. 比较并忽略所有空白差异 #

diff -w -B file1.txt file2.txt

12. 并排比较并抑制相同行 #

diff -y --suppress-common-lines file1.txt file2.txt

与其他命令结合使用 #

1. 将差异保存到文件 #

diff -u file1.txt file2.txt > changes.patch

2. 应用差异(补丁) #

patch file1.txt < changes.patch

3. 比较压缩文件 #

zdiff file1.gz file2.gz

4. 比较两个命令的输出 #

diff <(command1) <(command2)

5. 查找目录中所有不同的文件 #

diff -rq dir1 dir2

6. 比较并高亮显示差异 #

diff -u file1.txt file2.txt | colordiff

7. 比较排序后的文件内容 #

diff <(sort file1.txt) <(sort file2.txt)

实用示例 #

1. 比较配置文件 #

diff -u /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

2. 查找两个代码版本的差异 #

diff -r -u project-v1/ project-v2/

3. 比较两个文件并忽略注释行 #

diff <(grep -v '^#' file1.txt) <(grep -v '^#' file2.txt)

4. 比较两个CSV文件的特定列 #

diff <(cut -d, -f2 file1.csv) <(cut -d, -f2 file2.csv)

5. 比较两个目录中的文件列表 #

diff <(ls -la dir1) <(ls -la dir2)

6. 比较两个文件的行数 #

diff <(wc -l file1.txt) <(wc -l file2.txt)

7. 比较两个文件并显示百分比差异 #

diff --suppress-common-lines -y file1.txt file2.txt | grep -v '($|^$)' | wc -l

然后将结果除以文件的总行数。

相关命令 #

  • cmp:按字节比较文件
  • comm:比较两个已排序的文件
  • sdiff:并排合并文件差异
  • vimdiff:使用Vim比较文件
  • colordiff:带颜色的diff
  • wdiff:按单词比较文件
  • meld:图形化差异查看器
  • kdiff3:图形化三路差异查看器和合并工具

提示 #

  • 使用-u选项生成统一格式的差异,这是最常用的格式,也是版本控制系统如Git使用的格式
  • 使用-w选项可以忽略空白差异,这在比较代码时特别有用
  • 使用-B选项可以忽略空行差异,这在比较有不同格式的文本时很有用
  • 使用-r选项可以递归比较目录,这在比较项目版本时很有用
  • 使用-q选项可以快速检查文件是否不同,而不显示详细差异
  • 使用--color选项可以使差异更容易识别
  • 在脚本中,可以使用diff的退出状态来确定文件是否不同:0表示相同,1表示不同,2表示出错
  • 对于二进制文件,使用cmp命令而不是diff
  • 对于大文件,考虑使用diff -q先检查是否不同,再决定是否查看详细差异
  • 使用进程替换<(command)可以比较命令输出而不创建临时文件