diff是Linux系统的一个很重要的工具程序,我们通常用diff对同一软件(或程序)的不同版本的文件进行对比查看。不过,你不要用diff去比较两个完全不相干的文件,因为那样是比不出结果来的。最后提醒一下,diff是以“行”为单位比较的哦。diff和patch是一对工具,在数学上来说,diff是对两个集合的差运算,patch是对两个集合的和运算。diff比较两个文件或文件集合的差异,并记录下来,生成一个diff文件,这也是我们常说的patch文件,即补丁文件。patch能将diff文件运用于原来的两个集合之一,从而得到另一个集合。举个例子来说文件A和文件B,经过diff之后生成了补丁文件C,那么这个过程相当于 A -B = C ,那么patch的过程就是B+C= A 或A-C =B。因此我们只要能得到A, B, C三个文件中的任何两个,就能用diff和patch这对工具生成另外一个文件。好啦,还是老规矩,咱们先整个diff的实例,举个栗子吧。
初始时file.old文件内容(看清楚了哦,这个就算是软件或程序更新前的旧版本咯)
现在我们通过原文件生成新版本文件
命令解释:sed对cat输出到终端的file.old内容进行修改(是对终端缓存的修改,不是对原文件的修改哦),’5d’(删除原文件第5行内容)、’6c new six line’(将原文件第6行的内容替换为:new six line)、’7a append new line’(在原文件第7行后追加:append new line),最后将修改过的终端缓存内容重定向到file.new文件中。
先“ll”一下,看看两个文件的大小吧!
新文件file.new内容(看清楚了哦,这个就算是软件或程序更新后的新版本咯),看出什么来了么?哈哈,不仔细看是看不出端倪的。是不是觉得肉眼对比的工作太枯燥无味啦,要是文件时上万行的,是不是简直到崩溃掉。你可能会想到git,但是咱们有diff哦,这个时候就到了diff大显身手的时候了。
咱们使用diff的普通查看模式先对照一下区别吧(什么,普通模式,难道还有其他模式么?当然啦,一会儿后面会给大家介绍到,不要急躁,咱们先一起来看看普通模式吧)
解释命令执行结果:
5,6c5:表示file.old的第5行和第6行发生了改变,被file.new的第5行所替换
7a7:表示在file.old的第7行后追加了数据,内容为file.new第7行的数据
<:表示被删除的内容
---:file.old和file.new的分隔符
>:表示增加的内容
接下来我要给大家介绍一个新命令patch,patch这个命令与diff可是有着密不可分的关系啊!上面我们说过,diff和patch是一对工具,在数学上来说,diff是对两个集合的差运算,patch是对两个集合的和运算。diff比较两个文件或文件集合的差异,并记录下来,生成一个diff文件,这也是我们常说的patch文件,即补丁文件。patch能将diff文件运用于原来的两个集合之一,从而得到另一个集合。举个例子来说文件A和文件B,经过diff之后生成了补丁文件C,那么这个过程相当于 A -B = C ,那么patch的过程就是B+C= A 或A-C =B。因此我们只要能得到A, B, C三个文件中的任何两个,就能用diff和patch这对工具生成另外一个文件。
我们前面说到,diff可以用来分辨两个版本文件之间的区别,如上面举到的file.old和file.new之间就是两个不同版本的文件。那么,问题来了,如果“升级”了呢?也就是将旧版本文件升级为新版本文件时,我们要怎么做呢?这个时候就是patch命令发挥作用的时候啦,就是线比较新旧版本文件的区别,并将区别文件制作成补丁文件,再将补丁文件更新旧版本文件即可。补丁文件?可能有的小伙伴已经一脸懵逼了。哈哈哈,没关系啦,第一次我也是这样的哦。好啦,咱们来举个栗子吧,先生成补丁文件并查看一下补丁文件。
咱们先来了解一下patch命令参数吧:
patch [-pR] < patch_file
-p:后面的N表示取消几层目录的意思,“-pN”表示忽略路径中第N个斜线之前的目录。
-R:表示还原,将新的文件还原成原来的新版本
-u:表示在比较结果中输出上下文中一些相同的行,这有利于人工定位
-r:表示递归比较各个子目录下的文件
-N:将不存在的文件当作空文件
-w:忽略空格的区别
-B:忽略空行的区别
-i:忽略大小写的不同
将新旧版本文件输出到终端,肉眼先对比一下
咱们使用diff工具程序来对比一下
还原文件内容(给你一个【ctrl+z】的机会,怕你误操作了,哈哈哈~),这个主要是得到另外一个集合。
diff后面可以接两个文件名或两个目录名。如果是一个目录名加一个文件名,那么只作用在那么个目录下的同名文件。如果是两个目录的话,作用于该目录下的所有文件,不递归。如果我们希望递归执行,需要使用-r参数。下面我们来演示一下目录的打补丁,以及集合之间的相互转换。
看到了没,A、B、C三个集合,只要得到其中任意两个集合,我们就可以得到剩下的一个集合,学会了么?可能有的小伙伴会问:“为什么不直接在当前目录下操作呢?把补丁文件拷贝过去在操作多麻烦哈”。一般建议这么做,因为这样不会出错,举个栗子你就明白了,还是拿上面的栗子吧。
注意到了么?当目标文件不存在的时候操作时没有问题的。但是,当目标文件存在的时候,就会出现上面的情况(将原文件夹删除、生成错误文件rej)。一般建议使用博主前面的方式来操作,当然,如果你要使用后面的操作方式也可以,只是你要保证操作的目标文件不存在才行。
刚才我们已经使用过了diff的普通模式了,那现在我们再来看看另外两种模式吧!使用Linux的前辈们觉得diff普通模式下显示的结果太简单,他们认为最好加入上下文,便于了解发生的变动。因此,推出了上下文格式的diff。
随着人们对diff的使用,问题不断涌出,既然有上下文模式,那么问题来了。如果两个文件相似度很高,那么上下文格式的diff将显示大量重复的内容,很浪费空间,顺势便产生了合并模式。
关于diff和patch工具程序的使用就介绍到这里啦,希望你已经学会了使用它。哈哈哈,多弄几个栗子练习一下吧!