首頁 > 軟體

Linux中diff、修補程式的用法及介紹

2020-06-16 17:04:41

首先介紹一下diff和patch。在這裡不會把man線上文件上所有的選項都介紹一下,那樣也沒有必要。在99%的時間裡,我們只會用到幾個選項。所以必須學會這幾個選項。

diff
NAME
diff - find differences between two files
 
SYNOPSIS
diff [options] from-file to-file

簡單的說,diff的功能就是用來比較兩個檔案的不同,然後記錄下來,也就是所謂的diff修補程式。語法格式:diff 【選項】 原始檔(夾) 目的檔案(夾),就是要給原始檔(夾)打個修補程式,使之變成目的檔案(夾),術語也就是“升級”。下面介紹三個最為常用選項:
-r 是一個遞迴選項,設定了這個選項,diff會將兩個不同版本原始碼目錄中的所有對應檔案全部都進行一次比較,包括子目錄檔案。
-N 選項確保修補程式檔案將正確地處理已經建立或刪除檔案的情況。
-u 選項以統一格式建立修補程式檔案,這種格式比預設格式更緊湊些。
 
diff是Unix系統的一個很重要的工具程式。
它用來比較兩個文字檔案的差異,是程式碼版本管理的基石之一。你在命令列下,輸入:
  $ diff <變動前的檔案> <變動後的檔案>
diff就會告訴你,這兩個檔案有何差異。它的顯示結果不太好懂,下面我就來說明,如何讀懂diff。

一、diff的三種格式
由於歷史原因,diff有三種格式:
  * 正常格式(normal diff)
  * 上下文格式(context diff)
  * 合併格式(unified diff)
我們依次來看。

二、範例檔案
為了便於講解,先新建兩個範例檔案。
第一個檔案叫做f1,內容是每行一個a,一共7行。
 a
  a
  a
  a
  a
  a
  a

第二個檔案叫做f2,修改f1而成,第4行變成b,其他不變。
 a
  a
  a
  b
  a
  a
  a

三、正常格式的diff
現在對f1和f2進行比較:
  
$ diff f1 f2

這時,diff就會顯示正常格式的結果:
  
 4c4
  < a
  ---
  > b

第一行是一個提示,用來說明變動位置。
 
  4c4

它分成三個部分:前面的"4",表示f1的第4行有變化;中間的"c"表示變動的模式是內容改變(change),其他模式還有"增加"(a,代表addition)和"刪除"(d,代表deletion);後面的"4",表示變動後變成f2的第4行。
第二行分成兩個部分。
  
 < a

前面的小於號,表示要從f1當中去除該行(也就是第4行),後面的"a"表示該行的內容。
第三行用來分割f1和f2。
 
  ---

第四行,類似於第二行。
  
 > b

前面的大於號表示f2增加了該行,後面的"b"表示該行的內容。
最早的Unix(即AT&T版本的Unix),使用的就是這種格式的diff。
 
四、上下文格式的diff
上個世紀80年代初,加州大學伯克利分校推出BSD版本的Unix時,覺得diff的顯示結果太簡單,最好加入上下文,便於了解發生的變動。因此,推出了上下文格式的diff。
它的使用方法是加入c引數(代表context)。
   $ diff -c f1 f2

顯示結果如下:
  
 *** f1 2012-08-29 16:45:41.000000000 +0800
  --- f2 2012-08-2916:45:51.000000000 +0800
  ***************
  *** 1,7 ****
   a
   a
   a
  !a
   a
   a
   a
  --- 1,7 ----
   a
   a
   a
  !b
   a
   a
   a

這個結果分成四個部分。
第一部分的兩行,顯示兩個檔案的基本情況:檔名和時間資訊。
  
 *** f1 2012-08-29 16:45:41.000000000 +0800
  --- f2 2012-08-2916:45:51.000000000 +0800

"***"表示變動前的檔案,"---"表示變動後的檔案。
第二部分是15個星號,將檔案的基本情況與變動內容分割開。
   ***************

第三部分顯示變動前的檔案,即f1。
  
 *** 1,7 ****
   a
   a
   a
  !a
   a
   a
   a

這時不僅顯示發生變化的第4行,還顯示第4行的前面三行和後面三行,因此一共顯示7行。所以,前面的"*** 1,7 ****"就表示,從第1行開始連續7行。
另外,檔案內容的每一行最前面,還有一個標記位。如果為空,表示該行無變化;如果是感嘆號(!),表示該行有改動;如果是減號(-),表示該行被刪除;如果是加號(+),表示該行為新增。
第四部分顯示變動後的檔案,即f2。
  
 --- 1,7 ----
   a
   a
   a
  !b
   a
   a
   a

除了變動行(第4行)以外,也是上下文各顯示三行,總共顯示7行。
 
五、合併格式的diff
如果兩個檔案相似度很高,那麼上下文格式的diff,將顯示大量重複的內容,很浪費空間。1990年,GNU diff率先推出了"合併格式"的diff,將f1和f2的上下文合併在一起顯示。
它的使用方法是加入u引數(代表unified)。
  
$ diff -u f1 f2

顯示結果如下:
 ---f1 2012-08-29 16:45:41.000000000 +0800
  +++ f2 2012-08-2916:45:51.000000000 +0800
  @@ -1,7 +1,7 @@
   a
   a
   a
  -a
  +b
   a
   a
   a

它的第一部分,也是檔案的基本資訊。
 ---f1 2012-08-29 16:45:41.000000000 +0800
  +++ f2 2012-08-2916:45:51.000000000 +0800

"---"表示變動前的檔案,"+++"表示變動後的檔案。
第二部分,變動的位置用兩個@作為起首和結束。
 
 @@ -1,7 +1,7 @@

前面的"-1,7"分成三個部分:減號表示第一個檔案(即f1),"1"表示第1行,"7"表示連續7行。合在一起,就表示下面是第一個檔案從第1行開始的連續7行。同樣的,"+1,7"表示變動後,成為第二個檔案從第1行開始的連續7行。
第三部分是變動的具體內容。
 
   a
   a
   a
  -a
  +b
   a
   a
   a

除了有變動的那些行以外,也是上下文各顯示3行。它將兩個檔案的上下文,合併顯示在一起,所以叫做"合併格式"。每一行最前面的標誌位,空表示無變動,減號表示第一個檔案刪除的行,加號表示第二個檔案新增的行。

六、diff的用法:即打修補程式
[root@linuxidc /app]# diff -u f1 f2 > diff.log  #生成修補程式檔案diff.log
[root@linuxidc /app]# cat diff.log
--- f1  2017-10-13 18:12:51.604871346 +0800  #變動前檔案
+++ f2  2017-10-13 18:13:15.905871332 +0800  #變動後檔案
@@ -1,7 +1,7 @@                    #用兩個@作為起首和結束,-1,7:第一個檔案從第一行開始的連續七行;+1,7:第二個檔案從第一行開始的連續七行
 a
        a
        a  # 前面空表示無變動
-      a  # 減號表示第一個檔案刪除的行
+      b  # 加號表示第二個檔案新增的行    ,即第一個檔案和第二個檔案就區別在第二個檔案將第一個檔案裡的a換成了b
        a
        a
        a
[root@linuxidc /app]#

七、還原修補程式
 
[root@linuxidc /app]# ls                        #先檢視一下此時的檔案列表
diff.log  f1  f2  test
[root@linuxidc /app]# 
[root@linuxidc /app]# patch -b f1 diff.log        #還原修補程式,用f1,f2都可以 
patching file f1
[root@linuxidc /app]# ls
diff.log  f1  f1.orig  f2  test                  #可以看到f1自動生成了一個f1.orig的檔案
[root@linuxidc /app]# 
[root@linuxidc /app]# cat f1                      #現在f1裡放的是f2的檔案

        a
        a
        b
        a
        a
        a 
[root@linuxidc /app]# cat f1.orig              #f1原有的檔案被備份到了f1.orig檔案裡
a
        a
        a
        a
        a
        a
        a
[root@linuxidc /app]# mv f2 f2.orig            # 將f2檔案改名為f2.orig(為了跟還原的檔案比較)
[root@linuxidc /app]# ls
diff.log  f1  f1.orig  f2.orig  test
[root@linuxidc /app]# diff f1 f2.orig          # 沒有任何資訊輸出,表示兩個檔案內容完全一樣     
[root@linuxidc /app]# 
[root@linuxidc /app]# patch -b f2 diff.log      #借助f2還原也可以,只不過出現以下提示資訊(第一次看見以為是報錯資訊呢)
patching file f2
Reversed (or previously applied) patch detected!  Assume -R? [n] y    #輸入“y”回車就可以了
[root@linuxidc /app]# ls
diff.log  f1  f2  f2.orig  test
[root@linuxidc /app]# cat f2
a
        a
        a
        a
        a
        a
        a
[root@linuxidc /app]# cat f2.orig 
a
        a
        a
        b
        a
        a
        a
[root@linuxidc /app]#

本文永久更新連結地址http://www.linuxidc.com/Linux/2017-10/147631.htm


IT145.com E-mail:sddin#qq.com