zoukankan      html  css  js  c++  java
  • linux Linux diff与patch的深入分析

    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,需要人工合并文件的格式是一致的.

  • 相关阅读:
    Linux Shell脚本编程基础
    UBoot常用命令及内核下载与引导
    经典C面试真题精讲
    文本相似度分析(基于jieba和gensim)
    python中lambda,map,reduce,filter,zip函数
    机器学习-——损失函数
    Tensorflow中的数据对象Dataset
    github 相关操作知识
    机器学习——LightGBM
    机器学习——超参数搜索
  • 原文地址:https://www.cnblogs.com/zym0805/p/2352830.html
Copyright © 2011-2022 走看看