diff与patch,diff的三种模式说明

diff与patch,diff的三种模式说明

一个简单的文件比较

file1
1
2
3
4

file2
2
3
4
5

先从简单的说起:

  • -c 显示全部内文(context diff),并标出不同之处。
diff -c file1 file2
*** 1f  2016-03-19 14:49:39.881834600 +0800
--- 2f  2016-03-19 14:50:16.096849181 +0800
***************
*** 1,4 ****
- 1
  2
  3
  4
--- 1,4 ----
  2
  3
  4
+ 5

输出文件很易理解

  • -u 以合并的方式(unified diff)来显示文件内容的不同
diff -u file1 file2
--- file1.txt   2016-03-16 21:49:25.282579534 +0800
+++ file2.txt   2016-03-18 15:53:35.214591623 +0800
@@ -1,4 +1,4 @@
-1
 2
 3
 4
+5

第一部分,也是文件的基本信息:
“—”表示变动前的文件,”+++”表示变动后的文件。
第二部分,变动的位置用两个@作为起首和结束
前面的”-1,4”分成三个部分:减号表示第一个文件,”1”表示第1行,”4”表示连续4行。合在一起,就表示下面是第一个文件从第1行开始的连续4行。同样的,”+1,4”表示变动后,成为第二个文件从第1行开始的连续4行。


  • 比较复杂的就是正常模式(normal diff)的比较了
1d0
< 1
4a4
> 5

在解释上述指令之前,先来谈谈我理解的diff对处理文件的想法

  1. 对于两个较为相似的文本来说,经过替换,增加,删除一定能变成另外一个文本
  2. 当得知一个文本变成另外一个文本的方式,这个过程也是可逆的,即你同时也知道了相反的转变方法

正常模式就是来详述这一方式的

为什么是需要三个方法呢,替换、增加、删除感觉有重复啊?

diff重点是为了找出两个文件的差异,根据差异来修改,而不是简单复制或者大规模替换,因此是三个步骤

也可以说是两个,为什么呢?

来说一下diff 正常模式下可能出现的三个表达形式(r1,r2分别代表第一个,第二个文件的行数,可能是多行)

  • r1cr2 c为change
  • r1dr2 d为delete
  • r1ar2 a为add
  • <>分别代表1,2文本

diff file1 file2 是给出了file1到file2的变换方法,同时也给出了file2到file1的方法
理解上述指令为

  • r1与r2的内容互换
  • r1的文本删掉,放到r2的位置上来,含义是以前r2上方的文本(包括r2)向上移动,给新文本的位置
  • 与前一个类似,r2文本删掉,放到r1的位置,方法同上

可能会注意到我描述的方法与c,d,r的含义不同,这是因为c,d,r是站在第一个文本的角度上说的,而我两个文本一起而言的。
其实这样看来,2,3方法本质是一样的,所以可以看做是两种方法,移动和替换。

再强调一次,按照diff产生的结果做下去,两个文本内容替换

可以通过上述简单的例子验证

还有要特别注意的是,操作的方法
增加和删除都是最后的结果,并不是过程,每一步的操作均只针对原文本,而不是改动后的


一个稍微复杂的例子

file1内容为
a d z e g z
file2内容为
e d g g e z z f
diff file1 file2
1,3d0
< a
< d
< z
4a2
> d
5a4,6
> g
> e
> z
6a8
> f

建议试试上述过程,看结果是否正确

如果失败了,可以跟着我走一次此过程

  1. 1,3d0 将a-z删除并添加到file2上,结果为 a d z (e g z), (a d z e d g g e z z f)
  2. 4a2 删除file2的d并放到file1的第四行,结果为 a d z (e d g z), (a d z e) d (g g e z z f)
  3. 5a4,6 删除file2的4-6放到file1的第五行,结果为 a d z (e d g g e z z), (a d z e) d (g) g e z (z f)
  4. 6a8, 删除file2的8放到file的第六行,结果为 a d z (e d g g e z z f), (a d z e) d (g) g e z (z) f

对下列过程说明:

  • 为了表示每一步仍是在原文本上的改动,因此并没有删掉原文本,移动行数可对照原文本行数观察
  • 括号内为每一步产生的结果

如果你认为每一步可以拆分分别执行,可以先将diff结果输出保存,之后将文本分解,使用patch执行每一步操作看看最终结果是否正确

关于patch与diff的一点说明

这里只讨论简单的patch文件使用  

diff file1 file2 | patch 不可执行
diff -u file1 file2 | patch 可执行

为什么呢?
很简单,后者的diff中有对应的file1,file2,将其文件置于其他目录下,就无法执行了
如果只把file1移走呢?
会出现
Reversed (or previously applied) patch detected! Assume -R? [n]
输y的话就把file2的内容变成file1,正是逆操作(虽然是-u,但对于normal模式依旧试用)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值