9Linux操作命令comm,diff,patch

  • comm 命令
  • diff 命令
  • patch 命令

comm 命令

通常比较文本文件的内容很有帮助。对于系统管理员和软件开发者来说,这个尤为重要。一名系统管理员可能,例如,需要拿现有的配置文件与先前的版本做比较,来诊断一个系统错误。同样的,一名程序员经常需要查看程序的修改。

comm 命令将逐行比较已经排序的两个文件。显示结果包括 3 列:第 1 列为只在第一个文件中找到的行,第 2 列为只在第二个文件中找到的行,第 3 列为两个文件的共有行。

注意,comm 命令和 join、uniq 命令一样,只能用于已经排过序的数据。

(1)命令格式

1
comm [选项] 文件 1 文件 2

(2)常用参数

参数 描述
-1 不输出文件 1 特有的行
-2 不输出文件 2 特有的行
-3 不输出两个文件共有的行

(3)常用范例

  • 例一:比较 file1.txt 和 file2.txt 两个文件的内容,可以使用如下命令:
1
comm  file1.txt  file2.txt
  • 例二:比较 file1.txt 和 file2.txt 两个文件的内容,只显示两个文件共有的内容,可以使用如下命令:
1
comm  -12 file1.txt  file2.txt

diff 命令

类似 comm 命令,diff 命令被用来监测文件之间的差异。然而,diff 是一款更加复杂的工具,它支持许多输出格式,并且一次能处理许多文本文件。软件开发员经常使用 diff 程序来检查不同程序源码版本之间的更改,diff 能够递归地检查源码目录,经常称之为源码树。diff 程序的一个常见用例是创建 diff 文件或者补丁,它会被其它程序使用,例如 patch 程序(我们后面会讲到),来把文件从一个版本转换为另一个版本。

diff 在命令行中打印每一个行的改动,并且 diff 是 svn、cvs、git 等版本控制工具不可或缺的一部分。

diff 命令是 differential 的缩写。

(1)命令格式

1
diff [选项] 文件

(2)常用参数

参数 描述
-c 上下文模式,显示全部内文,并标出不同之处
-u 统一模式,以合并的方式来显示文件内容的不同
-a 只会逐行比较文本文件
-N 在比较目录时,若文件 A 仅出现在某个目录中,预设会显示:Only in 目录。 若使用-N 参数,则 diff 会将文件 A 与一个空白的文件比较
-r 递归比较目录下的文件

(3)常用范例

  • 例一:显示 file1.txt 和 file2.txt 两个文件的差异,可以使用如下命令:
1
diff  file1.txt  file2.txt

上面结果显示中的“1d0”表示 file1.txt 文件比 file2.txt 文件多了第一行,“4c3,4”表示 file1.txt 文件的第四行和 file2.txt 文件的第三、四行不同。

diff 的 normal 显示格式有三种提示:

1
2
3
a - add
c - change
d - delete
  • 例二:从上面例一的显示结果可以知道,file1.txt 和 file2.txt 两个文件的差异不易直观看出,可以使用上下文模式显示,可以使用如下命令:
1
diff  -c file1.txt  file2.txt

这个输出结果以两个文件名和它们的时间戳开头。第一个文件用星号做标记,第二个文件用短横线做标记。纵观列表的其它部分,这些标记将象征它们各自代表的文件。

1
*** 1,4 ***

表示第一个文件中第一行到第四行的文本行。

1
--- 1,4 ---

表示第二个文件中第一行到第四行的文本行。

三种特殊字符:

+ 添加行,这一行将会出现在第二个文件内,而不是第一个文件内

- 删除行,这一行将会出现在第一个文件中,而不是第二个文件内

! 更改行,将会显示某个文本行的两个版本,每个版本会出现在更改组的各自部分

这些特殊字符很容易混淆,实际上记住一点就行:所有操作目的是将第一个文件变成第二个文件。

  • 例三:查看 file1.txt 和 file2.txt 两个文件的差异,使用统一模式显示,可以使用如下命令:

diff -u file1.txt file2.txt
img

上下文模式和统一模式之间最显著的差异就是重复上下文的消除,这就使得统一模式的输出结果要比上下文模式的输出结果简短。

@@ -1,4 +1,4 @@ 表示在在更改组中描述的第一个文件中的文本行和第二个文件中的文本行。

特殊字符:

+ 添加这一行到第一个文件中
- 在第一个文件中删除这一行

patch 命令

patch 命令被用来把更改应用到文本文件中。它接受从 diff 程序的输出,并且通常被用来把较老的文件版本转变为较新的文件版本。让我们考虑一个著名的例子。Linux 内核是由一个大型的,组织松散的贡献者团队开发而成,这些贡献者会提交固定的少量更改到源码包中。这个 Linux 内核由几百万行代码组成,虽然每个贡献者每次所做的修改相当少。对于一个贡献者来说,每做一个修改就给每个开发者发送整个的内核源码树,这是没有任何意义的。相反,提交一个 diff 文件。一个 diff 文件包含先前的内核版本与带有贡献者修改的新版本之间的差异。然后一个接受者使用 patch 程序,把这些更改应用到他自己的源码树中。使用 diff/patch 组合提供了两个重大优点:

一个 diff 文件非常小,与整个源码树的大小相比较而言。

一个 diff 文件简洁地显示了所做的修改,从而允许程序补丁的审阅者能快速地评估它。

当然,diff/patch 能工作于任何文本文件,不仅仅是源码文件。它同样适用于配置文件或任意其它文本。

准备一个 diff 文件供 patch 命令使用,GNU 文档建议这样使用 diff 命令:

diff -Naur old_file new_file > diff_file

old file 和 new file 部分不是单个文件就是包含文件的目录。这个 r 选项支持递归目录树。

(1)命令格式

1
patch [选项] 补丁文件

(2)常用参数

参数 描述
-p num 忽略几层文件夹
-E 如果发现了空文件,那么就删除它
-R 取消打过的补丁

(3)常用范例

  • 例一:生成 file1.txt 和 file2.txt 的 diff 文件,然后应用 patch 命令更新 file1.txt 文件,可以使用如下命令:
1
2
diff  -Naur file1.txt  file2.txt > patchdiff.txt
patch < patchdiff.txt
  • 例二:取消上面例一打过的补丁,可以使用如下命令:
1
patch -R < patchdiff.txt