如何在 Linux 终端中比较两个文本文件

需要查看文本文件的两个修订版之间的差异吗? 然后 diff 是您需要的命令。 本教程向您展示了如何在 Linux 和 macOS 上以简单的方式使用 diff。

潜入差异

diff 命令比较两个文件并生成两者之间差异的列表。 更准确地说,它会生成一个需要对第一个文件进行更改的列表,以使其与第二个文件匹配。 如果你牢记这一点,你会发现更容易理解 diff 的输出。 diff 命令旨在查找源代码文件之间的差异并生成可以被其他程序读取和操作的输出,例如 修补 命令。 在本教程中,我们将研究使用差异的最有用的人性化方法。

让我们深入分析两个文件。 命令行上文件的顺序决定了哪个文件 diff 认为是“第一个文件”,哪个文件认为是“第二个文件”。 在下面的示例中,alpha1 是第一个文件,alpha2 是第二个文件。 这两个文件都包含 拼音字母 但是第二个文件 alpha2 进行了一些进一步的编辑,因此这两个文件并不相同。

我们可以用这个命令比较文件。 键入 diff、一个空格、第一个文件的名称、一个空格、第二个文件的名称,然后按 Enter。

diff alpha1 alpha2

我们如何剖析该输出? 一旦你知道要寻找什么,它就不是那么糟糕了。 每个差异都依次列在单个列中,并且每个差异都被标记。 标签包含字母两侧的数字,例如 4c4。 第一个数字是 alpha1 中的行号,第二个数字是 alpha2 中的行号。 中间的字母可以是:

c:需要更改第一个文件中的行以匹配第二个文件中的行。
d:必须删除第一个文件中的行以匹配第二个文件。
a: 必须在第一个文件中添加额外内容以使其与第二个文件匹配。

我们示例中的 4c4 告诉我们必须更改 alpha1 的第四行以匹配 alpha2 的第四行。 这是 diff 找到的两个文件之间的第一个区别。

以开头的行引用第二个文件 alpha2。 Dave 行告诉我们 Dave 这个词是 alpha2 中第四行的内容。 总结一下,我们需要在 alpha1 的第 4 行用 Dave 替换 Delta,以使该行在两个文件中都匹配。

下一个变化由 12c12 指示。 应用相同的逻辑,这告诉我们 alpha1 的第 12 行包含单词 Lima,但 alpha2 的第 12 行包含单词 Linux。

  如何在 Linux 上安装 Plex 媒体播放器

第三个变化是指从 alpha2 中删除的一行。 标签 21d20 被解读为“需要从第一个文件中删除第 21 行,以使两个文件从第 20 行开始同步”。 这

第四个差异标记为 26a26,28。 此更改涉及已添加到 alpha2 的三个额外行。 请注意标签中的 26,28。 用逗号分隔的两行数字表示一系列行号。 在此示例中,范围是从第 26 行到第 28 行。标签被解释为“在第一个文件的第 26 行,从第二个文件添加第 26 到 28 行”。 我们看到了需要添加到 alpha1 的 alpha2 中的三行。 这些包含单词 Quirk、Strange 和 Charm。

活泼的单线

如果您只想知道两个文件是否相同,请使用 -s(报告相同文件)选项。

diff -s alpha1 alpha3

您可以使用 -q(简要)选项来获得关于两个文件不同的同样简洁的声明。

diff -q alpha1 alpha2

需要注意的一件事是,对于两个相同的文件,-q(简要)选项完全隐藏起来,根本不报告任何内容。

另一种观点

-y(并排)选项使用不同的布局来描述文件差异。 在并排视图中使用 -W(宽度)选项通常很方便,以限制显示的列数。 这避免了使输出难以阅读的难看的环绕行。 在这里,我们告诉 diff 生成并排显示并将输出限制为 70 列。

diff -y -W 70 alpha1 alpha2

命令行上的第一个文件 alpha1 显示在左侧,命令行上的第二行 alpha2 显示在右侧。 每个文件的行并排显示。 在 alpha2 中的那些行旁边有指示符字符已被更改、删除或添加。

|:第二个文件中已更改的行。
<: a="" line="" that="" has="" been="" deleted="" from="" the="" second="" file.="">: 已添加到第二个文件中但不在第一个文件中的行。

如果您希望对文件差异进行更紧凑的并排摘要,请使用 –suppress-common-lines 选项。 这会强制 diff 仅列出更改、添加或删除的行。

diff -y -W 70 --suppress-common-lines alpha1 alpha2

添加飞溅的颜色

另一个名为 colordiff 的实用程序将颜色突出显示到 diff 输出中。 这样可以更容易地查看哪些行有差异。

  如何使用 Electronplayer 在 Linux 桌面上观看 Hulu

如果您使用的是 Ubuntu 或其他基于 Debian 的发行版,请使用 apt-get 将此软件包安装到您的系统上。 在其他 Linux 发行版上,请改用您的 Linux 发行版的包管理工具。

sudo apt-get install colordiff

就像使用 diff 一样使用 colordiff。

实际上,colordiff 是 diff 的包装器,而 diff 在幕后完成了所有工作。 正因为如此,所有的 diff 选项都适用于 colordiff。

提供一些上下文

为了在屏幕上显示文件中的所有行和仅列出更改的行之间找到一些中间立场,我们可以要求 diff 提供一些上下文。 有两种方法可以做到这一点。 两种方式都达到了相同的目的,即在每条更改的行之前和之后显示一些行。 您将能够在检测到差异的位置查看文件中发生的情况。

第一种方法使用 -c(复制的上下文)选项。

colordiff -c alpha1 alpha2

diff 输出有一个标题。 标题列出了两个文件名及其修改时间。 有星号

在第一个文件的名称之前和破折号 (-) 在第二个文件的名称之前。 星号和破折号将用于指示输出中的行属于哪个文件。

中间带有 1,7 的星号行表示我们正在查看来自 alpha1 的行。 准确地说,我们正在查看第 1 到第 7 行。 Delta 一词被标记为已更改。 它旁边有一个感叹号(!),它是红色的。 该行前后显示了三行未更改的文本,因此我们可以在文件中看到该行的上下文。

中间有 1,7 的破折号线告诉我们,我们现在正在查看来自 alpha2 的线。 同样,我们正在查看第 1 到第 7 行,第 4 行中的单词 Dave 被标记为不同。

colordiff -C 2 alpha1 alpha2

每个更改上方和下方的三行上下文是默认值。 您可以指定要 diff 提供多少行上下文。 为此,请使用带有大写“C”的 -C(复制上下文)选项并提供您想要的行数:

colordiff -u alpha1 alpha2

提供上下文的第二个差异选项是 -u(统一上下文)选项。

和以前一样,我们在输出上有一个标题。 这两个文件被命名,并显示了它们的修改时间。 alpha1 的名称前有破折号 (-),alpha2 的名称前有加号 (+)。 这告诉我们,破折号将用于指代 alpha1,而加号将用于指代 alpha2。 整个列表中散布着以符号 (@) 开头的行。 这些线标志着每个差异的开始。 它们还告诉我们每个文件中显示了哪些行。

  如何使用 ps 命令监控 Linux 进程

我们显示了标记为不同的行之前和之后的三行,以便我们可以看到更改行的上下文。 在统一视图中,有差异的线在另一条之上显示。 来自 alpha1 的行前面有一个破折号,来自 alpha2 的行前面有一个加号。 这个显示在 8 行中实现了上面复制的上下文显示需要 15 行才能完成的工作。

colordiff -U 2 alpha1 alpha2

如您所料,我们可以要求 diff 准确提供我们希望看到的统一上下文行数。 为此,请使用带有大写“U”的 -U(统一上下文)选项并提供您想要的行数:

忽略空格和大小写

colordiff -y -W 70 test4 test5

让我们分析另外两个文件,test4 和 test5。 其中有六个超级英雄的名字。

结果表明,diff 发现与黑寡妇、蜘蛛侠和雷神系列没有什么不同。 它确实标志着美国队长、钢铁侠和绿巨人系列的变化。

那么有什么不同呢? 嗯,在 test5 中,Hulk 的拼写是小写的“h”,而美国队长在“Captain”和“America”之间有一个额外的空格。 好吧,这很明显,但是 Ironman 产品线有什么问题? 没有明显的差异。 这是一个很好的经验法则。 如果你看不到它,答案是空白。 在该行的末尾几乎可以肯定有一两个杂散空格或一个制表符。

如果它们对您无关紧要,您可以指示 diff 忽略特定类型的行差异,包括:
-i:忽略大小写的差异。
-Z:忽略尾随空格。
-b:忽略空白数量的变化。

-w:忽略所有空白更改。

colordiff -i -y -W 70 test4 test5

让我们让 diff 再次检查这两个文件,但这次忽略大小写的任何差异。

colordiff -i -Z -y -W 70 test4 test5

带有“The Hulk”和“The hulk”的行现在被认为是匹配的,小写的“h”没有区别。 让我们要求 diff 也忽略尾随空格。

colordiff -i -w -y -W 70 test4 test5

正如怀疑的那样,尾随空格一定是 Ironman 行的差异,因为 diff 不再标记该行的差异。 剩下的就是美国队长。 让我们让 diff 忽略大小写并忽略所有空白问题。

通过告诉 diff 忽略我们不关心的差异,diff 告诉我们,为了我们的目的,文件匹配。 diff 命令有更多选项,但其中大多数与生成机器可读输出有关。 这些可以在 Linux 上查看手册页

. 我们在上面的示例中使用的选项将使您能够使用命令行和人眼追踪文本文件版本之间的所有差异。