• 基础知识

  该命令的功能为逐行比较两个文本文件,列出其不同之处。它比comm命令完成更复杂的检查。它对给出的文件进行系统的检查,并显示出两个文件中所有不同的行,不要求事先对文件进行排序。

  语法:diff [选项] file1 file2

  说明:该命令告诉用户,为了使两个文件file1和file2一致,需要修改它们的哪些行。如果用“- ”表示file1或fiie2,则表示标准输入。如果file1或file2是目录,那么diff将使用该目录中的同名文件进行比较。

  例如: diff /usr/xu mine

  把目录/usr/xu 中名为mine的文件与当前目录中的mine文件进行比较。

  通常输出由下述形式的行组成:

  n1 a n3,n4

n1,n2 d n3

  n1,n2 c n3,n4 这些行类似ed命令把filel转换成file2。字母(a、d和c)之前的行号(n1,n2)是针对file1的,其后面的行号(n3,n4)是针对file2的。字母a、d和c分别表示附加、删除和修改操作。

  在上述形式的每一行的后面跟随受到影响的若干行,以“<”打头的行属于第一个文件,以“>”打头的行属于第二个文件

  diff能区别块和字符设备文件以及FIFO(管道文件),不会把它们与普通文件进行比较。

  如果file1和file2都是目录,则diff会产生很多信息。

  如果一个目录中只有一个文件,则产生一条信息,指出该目录路径名和其中的文件名。

  Diff 的common 选项的含义如下:

  - b 忽略行尾的空格,而字符串中的一个或多个空格符都视为相等。

  如How are you与How are you被视为相同的字符串。

  - c 采用上下文输出格式(提供三行上下文)。

  - C n 采用上下文输出格式(提供n行上下文)。

  - e 产生一个合法的ed脚本作为输出。

  - r 当file1和file2是目录时,递归作用到各文件和目录上。

  • 实例分析

diff的输出格式分为传统格式和统一格式

1)diff的传统格式输出.

############################################
cat before.txt
输出:
This is a line to be deleted
This is a line that will be changed
This is a line that will be unchanged

cat after.txt
输出: 
This is a line that has been changed
This is a line that will be unchanged
This is a line that has been added
############################################
diff before.txt after.txt 
输 出:
1,2c1
< This is a line to be deleted
< This is a line that will be changed
---
> This is a line that has been changed
3a3
> This is a line that has been added
############################################

注释:
传统格式的输出
1,2c1是指替换第1个文件的第1,2行到第2个文件的第2行,这里的1,2是指第1个文件的第1,2行,c是替换的意思,最后的1是第2个文件的第1行
<号是指第1个文件更改或删除的行
---号是分割两个文件
>号是第2个文件中增加或删除的行
3a3是指将第2个文件的第3行插入到第一个文件的第3行
也就是说第1个文件的:
< This is a line to be deleted
< This is a line that will be changed
被替换成第2个文件的:
> This is a line that has been changed
由于第1个文件的第3行和第2个文件的第2行一致,所以不做修改.
由于第2个文件的第3行是第1个文件所不具有的,所以在第1个文件的最后一行增加:
> This is a line that has been added

2)patch命令的应用

用diff的传统格式输出:
#################################
diff before.txt after.txt >mypatch.txt
#################################

用patch修补before.txt文件,使before.txt和after.txt一致.
#################################
cat mypatch.txt |patch before.txt 
输出:
patching file before.txt
#################################

比较两个文件,现在是一致的了.
#################################
cmp before.txt after.txt 
#################################

用patch命令恢复before.txt.
#################################
patch -R before.txt <mypatch.txt
输出:
patching file before.txt
#################################

注:-R标记告诉patch在反向上应用区别或者撤销patch.

再比较两个文件,现在不一致了.
#################################
cmp before.txt after.txt 
输出:
before.txt after.txt differ: byte 17, line 1
#################################

3)diff的统一格式输出.

#################################
diff -u before.txt after.txt |tee mypatch.diff
输出:
--- before.txt  2009-06-20 05:21:49.000000000 +0800
+++ after.txt   2009-06-20 04:03:16.000000000 +0800
@@ -1,3 +1,3 @@
-This is a line to be deleted
-This is a line that will be changed
+This is a line that has been changed
 This is a line that will be unchanged
+This is a line that has been added
#################################

注释:
diff -u选项是统一格式输出.
--- before.txt  2009-06-20 05:21:49.000000000 +0800
--- before.txt是指旧文件
+++ after.txt   2009-06-20 04:03:16.000000000 +0800
+++ after.txt是指新文件.
@@ -1,3 +1,3 @@
@@ -1,3是指第1个文件一共有3行,+1,3 @@是指第2个文件一共有3行.
-This is a line to be deleted
-This is a line that will be changed
是被删除的行
+This is a line that has been changed
是增加的行
 This is a line that will be unchanged
没有-号和+号是指该行不变,因为after.txt和before.txt都有这行.
+This is a line that has been added
是增加的行
diff的统一格式比较与输出是按顺序进行的.

4)diff命令在目录中的应用.

新建old和new目录,old目录包含了初始内容,new目录包含文件的最新版本.
##########################################
mkdir old new
echo "This is one. It's unchanged." | tee old/one new/one
echo "This is two. It will change." > old/two
echo "This is two. It changed.">new/two
echo "This is three. It's new" > new/three
##########################################

创建修补文件
##########################################
diff -Nur old/ new/ >mypatch.diff
##########################################
注:-r选项按照文件目录递归创建修补文件.
-u还是统一模式
-N是指当diff遇到一个只存在于两个树中的一个树中的文件时,默认情况下跳过文件并且打印一个警告到stderr.
这个行为可以通过-N选项来更改,这也导致了diff认为丢失的文件实际上是存在的,但它是空的.采用这种方式,
一个修补文件可以包括已经创建的文件.然后应用修补程序创建新的文件.

##########################################
more mypatch.diff 
输出:
diff -Nur old/three new/three
--- old/three   1970-01-01 08:00:00.000000000 +0800
+++ new/three   2009-06-20 06:55:34.000000000 +0800
@@ -0,0 +1 @@
+This is three. It's new
diff -Nur old/two new/two
--- old/two     2009-06-20 06:55:08.000000000 +0800
+++ new/two     2009-06-20 06:55:21.000000000 +0800
@@ -1 +1 @@
-This is two. It will change.
+This is two. It changed.
##########################################
注释:
diff -Nur old/three new/three是指下面比较old/three new/three两个文件.
因为没有old/three文件,所以在old/three中增加+This is three. It's new
diff -Nur old/two new/two是指下面比较old/two new/two两个文件
因为old/two与new/two的第3行不一致,所以删除This is two. It will change.增加This is two. It changed.

打补丁到old目录,新建old/three以及更改old/two
##########################################
patch --dir old< mypatch.diff
ls -l     old/
输出:
one    three  two 
##########################################

恢复old目录的内容,包括删除old/three,以及恢复old/two文件
##########################################
patch --dir old -R <mypatch.diff
输出:
ls -l old/
one  two  
##########################################

5)检查和合并更改

用vim突出显示单个字符的更改来表示区别.

##########################################
vim -d after.txt before.txt
##########################################

用gui工具gvimdiff来显示两个文件.

##########################################
gvimdiff after.txt before.txt
##########################################

新建文件orig.c

##########################################
vi orig.c 
void foo(void)
{
    printf("This will be changed by me. /n");

printf("This will be unchanged,/n");

printf("This will be changed by you./n");
}
##########################################

复制文件orig.c到me.c,更改第4行为printf("This was changed by me. /n");
##########################################
vi me.c 
void foo(void)
{
    printf("This was changed by me. /n");

printf("This will be unchanged,/n");

printf("This will be changed by you./n");
}
##########################################

复制文件orig.c到you.c,更改第7行为printf("This was changed by you./n");
##########################################
vi you.c 
void foo(void)
{
    printf("This will be changed by me. /n");

printf("This will be unchanged,/n");

printf("This was changed by you./n");
}
##########################################

版本工具如cvs,subversion使用GNU合并工具称为diff3.
##########################################
diff3 me.c orig.c you.c 
输出:
====1
1:3c
      printf("This was changed by me. /n");
2:3c
3:3c
      printf("This will be changed by me. /n");
====3
1:7c
2:7c
      printf("This will be changed by you./n");
3:7c
      printf("This was changed by you./n");

注:
在没有参数的情况下,diff3产生的输出说明了那行更改.
====1和====3指明造成同原始文件不同的是哪一个修改文件.
编号方式基于参数序列.
也就是第1个文件和第3个文件与原文件不同.
1:3c
      printf("This was changed by me. /n");
3:3c
      printf("This will be changed by me. /n");
1:3c表示第1个文件的第3行与3:3c表示的第3个文件的第3行不同.
为什么不显示与原文件的比较呢。因为第3个文件的第3行与源文件(第2个文件)相同.所以与哪个文件比较无所谓了.

2:7c
      printf("This will be changed by you./n");
3:7c
      printf("This was changed by you./n");
2:7c表示第2个文件的第7行与3:7c表示的第3个文件的第7行不同.

diff3会试图为我们进行合并.合并是在源文件的基础上,依据两个新文件进行修改
源文件是第二个文件,第一个文件和第三个文件可以互换,但他们必须有共同的祖先,就是第二个文件.

#######################################
diff3 -m me.c orig.c you.c |cat -n
输出:
     1    void foo(void)
     2    {
     3        printf("This was changed by me. /n");
     4    
     5        printf("This will be unchanged,/n");
     6    
     7        printf("This was changed by you./n");
     8    }
########################################

为了测试更复杂的环境,新建一个文件orig.c.1
内容如下:
########################################
vi orig.c.1 
void foo(void)
{
    printf("This will be changed by both of us./n");
}
########################################

用diff3 -m再次比较输出,如下:
########################################
diff3 -m me.c orig.c.1 you.c 
void foo(void)
{
<<<<<<< me.c
    printf("This was changed by me. /n");

printf("This will be unchanged,/n");

printf("This will be changed by you./n");
||||||| orig.c.1
    printf("This will be changed by both of us./n");
=======
    printf("This will be changed by me. /n");

printf("This will be unchanged,/n");

printf("This was changed by you./n");
>>>>>>> you.c
}
########################################

注释:以上的格式,同cvs update,需要人工合并文件的格式是一致的.

diff & pattch 命令的更多相关文章

  1. linux diff(differential) 命令

    功能说明:比较文件的差异. 语法:diff [OPTION]... FILES 实例: diff -ur temp1 temp2 diff -ur temp1 temp2 > temp.diff ...

  2. linux diff命令

    diff 命令是 linux上非常重要的工具,用于比较文件的内容,特别是比较两个版本不同的文件以找到改动的地方.diff在命令行中打印每一个行的改动.最新版本的diff还支持二进制文件.diff程序的 ...

  3. 每天一个linux命令(36):diff 命令

    diff 命令是 linux上非常重要的工具,用于比较文件的内容,特别是比较两个版本不同的文件以找到改动的地方.diff在命令行中打印每一个行的改动.最新版本的diff还支持二进制文件.diff程序的 ...

  4. linux中diff命令用法

    diff 命 令是 linux上非常重要的工具,用于比较文件的内容,特别是比较两个版本不同的文件以找到改动的地方.diff在命令行中打印每一个行的改动.最新版 本的diff还支持二进制文件.diff程 ...

  5. 每天一个linux命令(28):diff 命令

    diff 命 令是 linux上非常重要的工具,用于比较文件的内容,特别是比较两个版本不同的文件以找到改动的地方.diff在命令行中打印每一个行的改动.最新版 本的diff还支持二进制文件.diff程 ...

  6. 进入git diff 界面,无法继续输入命令

    在终端,输入 git diff 文件名  命令之后回车,显示如下界面: 在网上查找,说输入q回车即可退出显示,执行,果然有效,输入h可以显示所有命令 命令如下: SUMMARY OF LESS COM ...

  7. 每天一个命令day1【diff 命令】(具体实例看下一节)

    diff 命令是 linux上非常重要的工具,用于比较文件的内容,特别是比较两个版本不同的文件以找到改动的地方.diff在命令行中打印每一个行的改动.最新版本的diff还支持二进制文件.diff程序的 ...

  8. 每天一个linux命令(49)--diff命令

    diff 命令是 Linux 上非常重要的工具,用于比较文件的内容,特别是比较两个版本不同的文件以找到改动的地方.diff 在命令行中打印每一个行的改动.最新版本的diff还支持二进制文件,diff ...

  9. linux命令-diff对比文件工具

    diff 命令是 linux上非常重要的工具,用于比较文件的内容,特别是比较两个版本不同的文件以找到改动的地方.diff在命令行中打印每一个行的改动.最新版本的diff还支持二进制文件.diff程序的 ...

随机推荐

  1. CF461B Appleman and Tree (树DP)

    CF462D Codeforces Round #263 (Div. 2) D Codeforces Round #263 (Div. 1) B B. Appleman and Tree time l ...

  2. [译]git rebase -i

    使用rebase -i会在终端出现一个交互页面. 在这个交互页面中我们可以对要rebase的commit做一定的修改. 用法 git rebase -i <master> 把当前的分支的c ...

  3. 编译本地64位版本的hadoop-2.6.0

     官方提供的hadoop-2.x版本貌似都是32位的,在64位机子下使用可能会报错,最好使用官方提供的源码进行本地编译,编译成适合本地硬件环境的64位软件包. 关于native  Hadoop是使用J ...

  4. MongoDB副本集学习(三):性能和优化相关

    Read Preferences/读写分离 有时候为了考虑应用程序的性能或响应性,为了提高读取操作的吞吐率,一个常见的措施就是进行读写分离,MongoDB副本集对读写分离的支持是通过Read Pref ...

  5. Handler Should be static or leaks Occur?

    解决办法: public class SampleActivity extends Activity { /** * Instances of static inner classes do not ...

  6. MongoDB的安全(五)

    MongoDB用户管理操作: MongoDB开启权限认证的方式有两种一种是auth形式,一种是keyfile形式 MongoDB创建用户: 1. 创建用户语法:在MongoDB2.6版本之后使用cre ...

  7. 1.xrange和range不要混了,2.range(len(xx))不如用enumerate

    range()是列表, xrange()是迭代 >>> a = ['Mary', 'had', 'a', 'little', 'lamb'] >>> for i i ...

  8. Caffe学习系列(14):Caffe代码阅读

    知乎上这位博主画的caffe的整体结构:https://zhuanlan.zhihu.com/p/21796890?refer=hsmyy Caffe 做train时的流程图,来自http://caf ...

  9. linux下使用ffmpeg将amr转成mp3

    说明:AMR格式是智能手机上的常用音频文件格式,比MP3格式的压缩比大.同样时长的AMR文件大概是MP3的十分之一,所以在移动互联项目中应用比较广泛.但目前AMR格式在个人电脑上应用较少,所以目前大部 ...

  10. Linux下端口被占用解决

      有时候关闭软件后,后台进程死掉,导致端口被占用.下面以JBoss端口8083被占用为例,列出详细解决过程. 解决方法: 1.查找被占用的端口 netstat -tln netstat -tln | ...