首页 > 代码库 > diff 和 patch 双剑合璧

diff 和 patch 双剑合璧

diff可以比较两个文件的不同,也可以比较两个文件夹的不同,并可以生成补丁文件

# 准备俩不同的文件
[root@console tmp]# cat old
A:Hello,Good morning
B:Hello,How are you? I am Hai Meimei.
A:Fine. Tank you, and you?
B:I am fine too.
[root@console tmp]# cat new
A:Hello,Good morning
B:Hello,How are you? I am Hai Meimei.
A:Fine. Thank you, and you? I am Li Lei.
B:I am fine too.

# 默认显示格式是--normal,可缺省
[root@console tmp]# diff old new
3c3        # 两个文件第三行不同,分别是什么
< A:Fine. Tank you, and you?
---
> A:Fine. Thank you, and you? I am Li Lei.

# 比对结果重定向输出到文件就是一个补丁文件,可以这个补丁文件给老文件打补丁
[root@console tmp]# diff old new > 1.patch
[root@console tmp]# cat 1.patch 
3c3
< A:Fine. Tank you, and you?
---
> A:Fine. Thank you, and you? I am Li Lei.

# -c --context 以上下文格式,显示的比较全,但也比较繁多
[root@console tmp]# diff -c old new
*** old	2014-08-14 03:45:34.524343092 +0800
--- new	2014-08-14 03:45:42.268157302 +0800
***************
*** 1,4 ****
  A:Hello,Good morning
  B:Hello,How are you? I am Hai Meimei.
! A:Fine. Tank you, and you?
  B:I am fine too.
--- 1,4 ----
  A:Hello,Good morning
  B:Hello,How are you? I am Hai Meimei.
! A:Fine. Thank you, and you? I am Li Lei.
  B:I am fine too.
  
# -u --unified 合并的上下文,简洁明了多了
[root@console tmp]# diff -u old new
--- old	2014-08-14 03:45:34.524343092 +0800
+++ new	2014-08-14 03:45:42.268157302 +0800
@@ -1,4 +1,4 @@
 A:Hello,Good morning
 B:Hello,How are you? I am Hai Meimei.
-A:Fine. Tank you, and you?
+A:Fine. Thank you, and you? I am Li Lei.
 B:I am fine too.
 
 # 每种风格做出的补丁打上去的结果都必须是一样的
 [root@console tmp]# cp old old.bak
[root@console tmp]# diff -c old new > 2.patch
[root@console tmp]# cat 2.patch 
*** old	2014-08-14 03:45:34.524343092 +0800
--- new	2014-08-14 03:45:42.268157302 +0800
***************
*** 1,4 ****
  A:Hello,Good morning
  B:Hello,How are you? I am Hai Meimei.
! A:Fine. Tank you, and you?
  B:I am fine too.
--- 1,4 ----
  A:Hello,Good morning
  B:Hello,How are you? I am Hai Meimei.
! A:Fine. Thank you, and you? I am Li Lei.
  B:I am fine too.
[root@console tmp]# diff -u old new > 3.patch
[root@console tmp]# cat 3.patch 
--- old	2014-08-14 03:45:34.524343092 +0800
+++ new	2014-08-14 03:45:42.268157302 +0800
@@ -1,4 +1,4 @@
 A:Hello,Good morning
 B:Hello,How are you? I am Hai Meimei.
-A:Fine. Tank you, and you?
+A:Fine. Thank you, and you? I am Li Lei.
 B:I am fine too.
[root@console tmp]# patch old 1.patch 
patching file old
[root@console tmp]# cat old
A:Hello,Good morning
B:Hello,How are you? I am Hai Meimei.
A:Fine. Thank you, and you? I am Li Lei.
B:I am fine too.
[root@console tmp]# diff old new
[root@console tmp]# rm -f old
[root@console tmp]# cp old.bak old
[root@console tmp]# patch old 2.patch 
patching file old
[root@console tmp]# diff old new
[root@console tmp]# rm -f old
[root@console tmp]# cp old.bak old
[root@console tmp]# patch old 3.patch 
patching file old
[root@console tmp]# diff old new
[root@console tmp]#

对整个文件夹打补丁

diff 命令对文件夹做对比会分别对两个文件夹中的每一个文件做对比,最后生成的是一个补丁文件,打补丁的时候则依次应用到每一个文件。

# 对于有子文件夹的需要用-r --recusive 进行递归比较
[root@console tmp]# diff -ru test test1

# 注意这里的结构,有用patch打补丁时对于有子目录的情况要加 -p | --strip说明要跳过几个‘/’
# 来查找,如果用-p0 则在当前目录下先找test目录,然后依次向下找dir1目录,如果是 -p1 则跳过
# 第1个‘/’直接在当前目录下找dir1,然后接着往下找。
diff -ru test/dir1/file1 test1/dir1/file1
--- test/dir1/file1	2014-08-14 07:18:42.486913887 +0800
+++ test1/dir1/file1	2014-08-14 06:58:16.393590115 +0800
@@ -1 +1 @@
-file 1 
+file 1 new
diff -ru test/oldfile test1/oldfile
--- test/oldfile	2014-08-14 07:18:42.486913887 +0800
+++ test1/oldfile	2014-08-14 07:04:54.662944704 +0800
@@ -1,2 +1,2 @@
-我是一个兵。
+我是一个枪骑兵。
 i am a soldier.
diff -ru test/testfile test1/testfile
--- test/testfile	2014-08-14 07:18:42.486913887 +0800
+++ test1/testfile	2014-08-14 03:44:11.330355773 +0800
@@ -1,4 +1,4 @@
 A:Hello,Good morning
 B:Hello,How are you? I am Hai Meimei.
-A:Fine. Tank you, and you?
+A:Fine. Thank you, and you? I am Li Lei.
 B:I am fine too.
[root@console tmp]# diff -ru test test1 > test.patch

# 切到test目录,-p1 跳过第1个‘/‘从dir1开始
[root@console tmp]# cd test
[root@console test]# patch -p1 < ../test.patch
patching file dir1/file1
patching file oldfile
patching file testfile
[root@console test]# cd ..
[root@console tmp]# diff -ru test test1
[root@console tmp]# rm -rf test/*
[root@console tmp]# cp -r testbak/* test/
[root@console tmp]# cd test

# 重新来一次,但是这次不加-p1默认的就是-p0了,目录树对不上对应的子目录下的文件补丁就打不上了 
[root@console test]# patch < ../test.patch
can‘t find file to patch at input line 4
Perhaps you should have used the -p or --strip option?
The text leading up to this was:
--------------------------
|diff -ru test/dir1/file1 test1/dir1/file1
|--- test/dir1/file1	2014-08-14 07:18:42.486913887 +0800
|+++ test1/dir1/file1	2014-08-14 06:58:16.393590115 +0800
--------------------------
File to patch: 
Skip this patch? [y] y
Skipping patch.
1 out of 1 hunk ignored
patching file oldfile
patching file testfile
[root@console test]# diff -ru ../test ../test1
diff -ru ../test/dir1/file1 ../test1/dir1/file1
--- ../test/dir1/file1	2014-08-14 07:20:54.180727280 +0800
+++ ../test1/dir1/file1	2014-08-14 06:58:16.393590115 +0800
@@ -1 +1 @@
-file 1 
+file 1 new

# 如果做补丁文件的时候用的是全路径如下,那么打补丁时再切到test下的时候就注意要-p3略过2个‘/’也就是路过tmp和test两级目录
[root@console tmp]# diff -ru /tmp/test /tmp/test1
diff -ru /tmp/test/dir1/file1 /tmp/test1/dir1/file1
--- /tmp/test/dir1/file1	2014-08-14 07:34:23.189151910 +0800
+++ /tmp/test1/dir1/file1	2014-08-14 06:58:16.393590115 +0800
@@ -1 +1 @@
-file 1 
+file 1 new
diff -ru /tmp/test/oldfile /tmp/test1/oldfile
--- /tmp/test/oldfile	2014-08-14 07:34:23.189151910 +0800
+++ /tmp/test1/oldfile	2014-08-14 07:04:54.662944704 +0800
@@ -1,2 +1,2 @@
-我是一个兵。
+我是一个枪骑兵。
 i am a soldier.
diff -ru /tmp/test/testfile /tmp/test1/testfile
--- /tmp/test/testfile	2014-08-14 07:34:23.189151910 +0800
+++ /tmp/test1/testfile	2014-08-14 03:44:11.330355773 +0800
@@ -1,4 +1,4 @@
 A:Hello,Good morning
 B:Hello,How are you? I am Hai Meimei.
-A:Fine. Tank you, and you?
+A:Fine. Thank you, and you? I am Li Lei.
 B:I am fine too.
 
[root@console test]# patch -p3 < ../test2.patch 
patching file dir1/file1
patching file oldfile
patching file testfile
[root@console tmp]# diff -ru test test1
[root@console tmp]#

patch 不仅可以把老版本文件升级成新版本文件,同样可以降级回去,逆生长,咱这一点也不示弱

-R | --reverse 加-R参数就可以实现逆生长

-E | --remove-empty-files 如果遇到空文件则直接删除,如果需要的话

# 今年32明年23,逆生长成功
[root@console test]# patch -p1 -R < ../test.patch
patching file dir1/file1
patching file oldfile
patching file testfile
[root@console test]# diff -ru ../test ../test1
diff -ru ../test/dir1/file1 ../test1/dir1/file1
--- ../test/dir1/file1	2014-08-14 11:40:40.985576969 +0800
+++ ../test1/dir1/file1	2014-08-14 06:58:16.393590115 +0800
@@ -1 +1 @@
-file 1 
+file 1 new
diff -ru ../test/oldfile ../test1/oldfile
--- ../test/oldfile	2014-08-14 11:40:40.985576969 +0800
+++ ../test1/oldfile	2014-08-14 07:04:54.662944704 +0800
@@ -1,2 +1,2 @@
-我是一个兵。
+我是一个枪骑兵。
 i am a soldier.
diff -ru ../test/testfile ../test1/testfile
--- ../test/testfile	2014-08-14 11:40:40.985576969 +0800
+++ ../test1/testfile	2014-08-14 03:44:11.330355773 +0800
@@ -1,4 +1,4 @@
 A:Hello,Good morning
 B:Hello,How are you? I am Hai Meimei.
-A:Fine. Tank you, and you?
+A:Fine. Thank you, and you? I am Li Lei.
 B:I am fine too.


本文出自 “不懂IT的中医不是好IT” 博客,请务必保留此出处http://zhishen.blog.51cto.com/1612050/1540681