在 Linux 下使用 diff 命令比较两个文本文件时,默认输出是 传统“行差异”格式,即用一组标记、行号以及前缀符号来表示每处不同之处。理解和解读这些输出对于查看文件改动差异或合并修订非常重要。下面详细介绍**diff** 命令默认输出格式及如何阅读结果。


一、diff 命令基础

diff [选项] file1 file2
  • **diff file1 file2**:默认采用 行模式file1file2 对比,输出二者的差异。
  • 退出状态码
    • 0 表示两文件内容相同;
    • 1 表示有差异;
    • >1 表示出错(例如无法访问文件)。

如果文件差异很大或需要用于补丁合并,可用 **diff -u**(unified mode)或 diff -c(context mode)输出更直观格式。但最传统的 diff 输出样式(被称为 “normal diff”)如下所示:


二、diff 默认输出格式剖析

以一个简单的例子为参考:

1c1
< Hello world
---
> Hello Linux
2a3,4
> This is a new line
> Another new line

1. 命令中对比顺序

  • 运行 diff oldfile newfile 时:
    • 左尖括号 < 表示 oldfile 的内容;
    • 右尖括号 > 表示 newfile 的内容。

2. 变更标记的含义

在 “normal diff” 格式里,每一组差异都会用一行 “行号与操作符” + 后续 “文件差异” 来描述。

  • 行号和操作符

    • 例如 1c12a3,45d6 等,语法为:
      [旧文件行号][指令][新文件行号]
      
    • 其中指令(操作符)通常有三种:
      1. **a**:add(在新文件增加了某些行)
      2. **d**:delete(在旧文件删除了某些行)
      3. **c**:change(某些行内容被修改)
  • **尖括号 < >**:

    • **<**:表示这是旧文件的那部分内容
    • **>**:表示这是新文件的对应改动内容
  • --- 分割线

    • 当发生 c(change)时,旧文件内容和新文件内容之间会用一行 --- 做分隔。

示例解析

  1. 1c1

    • 说明 “旧文件的第 1 行 与 新文件的第 1 行 有变更”。
    • 接下来 diff 会输出旧文件第 1 行(用 < 开头),然后一行 --- 分隔,再输出新文件第 1 行(用 > 开头)。
  2. 2a3,4

    • 2a3,4 表示 “在旧文件第 2 行之后(a=add),在新文件中出现了 3,4 行新增内容”。
    • > This is a new line
    • > Another new line
    • 即新文件在旧文件第 2 行后面新增了两行(行号是 3 和 4)。
  3. 5d6

    • 如果出现 5d6,则表示 “旧文件第 5 行在新文件里被删除”,并且位置对应新文件的第 6 行附近。
    • **d**:delete

3. 行号范围说明

有时会看到形如 3,5c4,7

  • 代表旧文件第 3 行到第 5 行 (3,5) 被修改,并对应到新文件第 4 行到第 7 行 (4,7)。

三、阅读示例详解

假设有两个文件 old.txt / new.txt

**old.txt**:

1  Hello world
2  This is old file
3  End

**new.txt**:

1  Hello Linux
2  This is old file
3  This is a new line
4  Another new line
5  End

运行 diff old.txt new.txt,可能得到输出:

1c1
< Hello world
---
> Hello Linux
2a3,4
> This is a new line
> Another new line

解释:

  • 1c1
    • 旧文件第 1 行变为新文件第 1 行:
    • < Hello world
    • ---
    • > Hello Linux
    • 即:Hello worldHello Linux
  • 2a3,4
    • 表示在旧文件第 2 行之后,新文件插入了行号 3、4 的两行。
    • 新文件多出:
      • This is a new line
      • Another new line
    • 注:旧文件第 3 行“End”在新文件变成第 5 行,所以不会对其做 diff 提示,因为它还是相同内容,只是位置后移了。

(如果两端行数差异较大并出现删除/更多修改,还会显示 d 或更多行号范围。)


四、常用选项让输出更易读

  1. **-u / --unified**:统一格式(unified diff),常见于补丁文件,更现代、易读。示例:

    diff -u old.txt new.txt
    

    会输出几行上下文,形如:

    --- old.txt  2023-10-01 10:00:00.000000000 +0800
    +++ new.txt  2023-10-01 10:10:00.000000000 +0800
    @@ -1,3 +1,5 @@
    -Hello world
    +Hello Linux
     This is old file
    +This is a new line
    +Another new line
     End
    
  2. **-c**:上下文格式,类似 -u 但不同显示方式。

  3. **--color**:某些 diff 版本或在 Git Bash 下可用 --color=auto,让差异以颜色标出,阅读更直观。

  4. **-r**:递归比较目录,若 diff -r dir1 dir2 时,会逐个文件进行比较,适合对比两个源码目录。

  5. **-b / -w**:忽略空格差异,如 diff -w old.txt new.txt,不会提示仅由于空格数量改变而产生的差异。


五、总结

  • diff 默认输出(称为 Normal diff 格式)显示了“行号 操作符 行号”并用 <> 分别展示旧文件与新文件的差异行。
  • 核心操作符:
    • a → add,
    • d → delete,
    • c → change。
  • 通过行号如 “3,5c4,6” 可以看出旧文件第 3-5 行对应新文件第 4-6 行被修改。
  • 行开头 < 代表旧文件内容,> 代表新文件内容。
  • 如果想要更可读或可直接用于打补丁的格式,推荐使用 **diff -u**(统一 diff)。

理解这套规则后,就能读懂 diff 命令输出里各行之间的增删改情况,从而轻松对比文件或审阅补丁改动。