Linux 中的 diff 命令

diff 是一个命令行实用程序,使您可以逐行比较两个文件。它还可以比较目录的内容。

diff 命令最常用于创建一个补丁,其中包含一个或多个文件之间的差异,这个补丁可用于 patch 命令。

如何使用 diff 命令

diff 命令的语法如下:

diff [OPTION]... FILES

diff 命令可以以几种格式显示输出,其中最常用格式包括普通,上下文和统一格式。输出包含有关文件中哪些行必须更改以使它们变得相同的信息。如果文件匹配,则不产生任何输出。

要将命令输出保存到文件,可以使用重定向运算符:

diff file1 file2 > patch

在本文中,我们将使用以下两个文件来解释 diff 命令的工作方式:

文件1

Ubuntu
Arch Linux
Debian
CentOS
Fedora

文件2

Kubuntu
Ubuntu
Debian
Arch Linux
Centos
Fedora

普通格式

以最简单的形式,当 diff 命令在两个文本文件上运行且没有任何选项时,它将以正常格式生成输出:

diff file1 file2

输出将如下所示:

0a1
> Kubuntu
2d2
< Arch Linux
4c4,5
< CentOS
---
> Arch Linux
> Centos

普通输出格式由一个或多个描述差异的部分组成。每个部分如下所示:

change-command
< from-file-line...
---
> to-file-line...

0a12d24c4,5 是变化的命令。每个更改命令从左到右包含以下内容:

  • 第一个文件中的行号或行范围。
  • 一个特殊的更改字符。
  • 第二个文件中的行号或行范围。

更改字符可以是以下之一:

  • a - 添加行。
  • c - 换行。
  • d - 删除行。

更改命令后跟的完整行中,(<) 表示被删除的内容 , (>) 表示被添加到文件的内容。

让我们解释一下输出:

  • 0a1 -  file2 在 file1 的第 0 行之后,添加了 1 行。
    • > Kubuntu - 如上所述,file2 在 file1 的开头增加一行 Kubuntu。
  • 2d2 - 删除 file1 中的第 2 行。在 d 符号后的 2 表示,如果该行不删除,将出现在第二个文件第 2 行。
    • < Arch Linux - 删除的行。
  • 4c4,5- 第二个文件中的 4-5 行是替换(更改)第一个文件中的 4 行 。
    • < CentOS - 第一个文件中要替换的行。
    • --- - 分隔器。
    • > Arch Linux> Centos- 从所述第二文件中新替换的行。

上下文格式

使用上下文输出格式时,该 diff 命令会在文件之间不同的行周围显示几行上下文。

-c 选项指示 diff 以上下文格式产生输出:

diff -c file1 file2
*** file1	2019-11-25 21:00:26.422426523 +0100
--- file2	2019-11-25 21:00:36.342231668 +0100
***************
*** 1,6 ****
  Ubuntu
- Arch Linux
  Debian
! CentOS
  Fedora

--- 1,7 ----
+ Kubuntu
  Ubuntu
  Debian
! Arch Linux
! Centos
  Fedora

如果比较了文件,则输出以名称和时间戳开始,以及一个或多个描述差异的部分开始。每个部分如下所示:

***************
*** from-file-line-numbers ****
  from-file-line...
--- to-file-line-numbers ----
  to-file-line...
  • from-file-line-numbersto-file-line-numbers - 逗号分隔的行号表示第一个和第二个文件的行范围。
  • from-file-lineto-file-line- 不同的行差异:
    • 以两个空格开头的行是上下文行,这两个文件中的行相同。
    • 以减号(-)开头的行是第二个文件已经删除了该行
    • 以加号(+)开头的行是相对于第一个文件,第二个文件增加的行。
    • 以感叹号(!)开头的行是在两个文件之间更改的行。

让我们解释输出中最重要的部分:

  • 在此示例中,我们只有一节描述了差异。
  • *** 1,6 ****--- 1,7 ---- 告诉我们本节中包含的第一个文件和第二个文件中的行范围。
  • UbuntuDebianFedora,最后的空行是在这两个文件是相同的。这些行以双倍空格开头。
  • - Arch Linux 从第一个文件中删除的行。尽管第二行中也存在此行,但是位置不同。
  • + Kubuntu 第二个文件增加的行。
  • 第一个文件的行 ! CentOS 和第二个文件中的 ! Arch Linux! CentOS 是不同的。

默认情况下,上下文行的数量默认为三。要指定另一个数字,请使用 -C(--contexts) 选项:

diff -C 1 file1 file2
*** file1	2019-11-25 21:00:26.422426523 +0100
--- file2	2019-11-25 21:00:36.342231668 +0100
***************
*** 1,5 ****
  Ubuntu
- Arch Linux
  Debian
! CentOS
  Fedora
--- 1,6 ----
+ Kubuntu
  Ubuntu
  Debian
! Arch Linux
! Centos
  Fedora

统一格式

统一输出格式是上下文格式的改进版本,并产生较小的输出。

使用 -u 选项告诉 diff 以统一格式打印输出:

diff -u file1 file2
--- file1	2019-11-25 21:00:26.422426523 +0100
+++ file2	2019-11-25 21:00:36.342231668 +0100
@@ -1,6 +1,7 @@
+Kubuntu
 Ubuntu
-Arch Linux
 Debian
-CentOS
+Arch Linux
+Centos
 Fedora

输出以文件的名称和时间戳以及描述差异的一个或多个部分开始。每个部分采用以下形式:

***************
@@ from-file-line-numbers to-file-line-numbers @@
 line-from-files...
  • @@ from-file-line-numbers to-file-line-numbers @@ -本节中包含的第一个和第二个文件的行号或行范围。
  • line-from-files - 不同的行和上下文的行:
    • 以两个空格开头的行是上下文行,这两个文件中的行相同。
    • 以减号 (-) 开头的行是从第一个文件中删除的行。
    • 以加号 (+) 开头的行是从第一个文件添加的行。

忽略大小写

您可能在上面的示例中注意到,该 diff 命令默认情况下区分大小写。

使用 -i 选项告诉 diff 忽略大小写:

diff -ui file1 file2
--- file1	2019-11-25 21:00:26.422426523 +0100
+++ file2	2019-11-25 21:00:36.342231668 +0100
@@ -1,6 +1,7 @@
+Kubuntu
 Ubuntu
-Arch Linux
 Debian
+Arch Linux
 CentOS
 Fedora

结论

比较文本文件之间的差异是 Linux 系统管理员最常见的任务之一。

diff 命令逐行比较文件的差异。有关更多信息,请在您的终端中输入 man diff