diff命令和patch命令的使用

diff命令和patch命令的使用

diff命令的使用方法

diff 命令是 linux上非常重要的工具,用于比較文件的內容,特別是比較兩個版本不同的文件以找到改動的地方。diff在命令行中打印每一個行的改動。最新版本的diff還支持二進制文件。diff程序的輸出被稱為補丁 (patch),因為Linux系統中還有一個patch程序,可以根據diff的輸出將a.c的文件內容更新為b.c。diff是svn、cvs、git等版本控制工具不可或缺的一部分。

一般使用方法

diff命令的格式一般為:

diff [參數][文件或者目錄1][文件或者目錄2]

例如,有文件test1和test2:

diff test1 test2

將會輸出:

2,3c2                       # 第一個文件的第2到第3行和第二個文件的第2行開始有沖突
< asfdasfdasdfasdf          # 刪去了兩行
< creverververver
---
> qwefqwefqwef              # 添加了這行
5,9c4                       # 第一個文件第五行到第九行和第二個文件第四行有沖突
< aaaaaaaaaaaa              # 刪去了了五行
< aaaa
< a
< a
< a
---
> qsdqwefqwefqwef           # 添加了一行
11d5                        # 第一個文件第11行與第二個文件第五行相比有刪除
< bbbbbbbbb                 # 刪除了這一行

格式的含義如注釋所示。

diff 的normal 顯示格式有三種提示:

a - add

c - change

d - delete

比較常用的是以合并的方式顯示兩個文件的不同:

diff -ruN test1 test2

輸出如:

--- test1   2016-04-21 14:46:55.000000000 +0800 # 第一個文件的信息
+++ test2   2016-04-21 14:44:55.000000000 +0800 # 第二個文件的信息
@@ -1,11 +1,5 @@                                # 第一個文件1到11行和第二個文件1到5行
 utils
-asfdasfdasdfasdf                               # 前面帶減號的是刪除的行
-creverververver
+qwefqwefqwef                                   # 帶加號的是增加的行
 util
-aaaaaaaaaaaa
-aaaa
-a
-a
-a
+qsdqwefqwefqwef
 qwerqwerqwe
-bbbbbbbbb

這種輸出方式輸出的內容可以用于使用patch命令進行打補丁包。patch命令我們稍后再看。

diff命令也可以比較兩個文件夾的不同:

例如有兩個文件夾testa和test,將test1和test2放進去:

diff testa testb

得到:

diff testa/test1 testb/test1    # 對比兩個文件夾下面文件名相同的文件
2,3c2                           # 以下是正常的文件對比格式
< asfdasfdasdfasdf
< creverververver
---
> qwefqwefqwef
5,9c4
< aaaaaaaaaaaa
< aaaa
< a
< a
< a
---
> qsdqwefqwefqwef
11d5
< bbbbbbbbb
Only in testa: test2            # testa里面有而testb里面沒有的test2
Only in testb: test3            # testa里面沒有而testb有的test3

diff命令的參數

  • -a或--text  diff預設只會逐行比較文本文件。
  • -b或--ignore-space-change  不檢查空格字符的不同。
  • -B或--ignore-blank-lines  不檢查空白行。
  • -c  顯示全部內文,并標出不同之處。

    diff -c test1 test2
    

    將會得到

    *** test1 2016-04-21 14:46:55.000000000 +0800
    --- test2 2016-04-21 14:44:55.000000000 +0800
    ***************
    *** 1,11 ****
      utils
    ! asfdasfdasdfasdf
    ! creverververver
      util
    ! aaaaaaaaaaaa
    ! aaaa
    ! a
    ! a
    ! a
      qwerqwerqwe
    - bbbbbbbbb
    --- 1,5 ----
      utils
    ! qwefqwefqwef
      util
    ! qsdqwefqwefqwef
      qwerqwerqwe
    

    其中:

    “+” 比較的文件的后者比前著多一行

    “-” 比較的文件的后者比前著少一行

    “!” 比較的文件兩者有差別的行

  • -C或--context  與執行"-c-"指令相同。
  • -d或--minimal  使用不同的演算法,以較小的單位來做比較。
  • -D或ifdef  此參數的輸出格式可用于前置處理器巨集。
  • -e或--ed  此參數的輸出格式可用于ed的script文件。
  • -f或-forward-ed  輸出的格式類似ed的script文件,但按照原來文件的順序來顯示不同處。
  • -H或--speed-large-files  比較大文件時,可加快速度。
  • -l或--ignore-matching-lines  若兩個文件在某幾行有所不同,而這幾行同時都包含了選項中指定的字符或字符串,則不顯示這兩個文件的差異。
  • -i或--ignore-case  不檢查大小寫的不同。
  • -l或--paginate  將結果交由pr程序來分頁。
  • -n或--rcs  將比較結果以RCS的格式來顯示。
  • -N或--new-file  在比較目錄時,若文件A僅出現在某個目錄中,預設會顯示:Only in目錄:文件A若使用-N參數,則diff會將文件A與一個空白的文件比較。
  • -p  若比較的文件為C語言的程序碼文件時,顯示差異所在的函數名稱。
  • -P或--unidirectional-new-file  與-N類似,但只有當第二個目錄包含了一個第一個目錄所沒有的文件時,才會將這個文件與空白的文件做比較。
  • -q或--brief  僅顯示有無差異,不顯示詳細的信息。
  • -r或--recursive  比較子目錄中的文件。
  • -s或--report-identical-files  若沒有發現任何差異,仍然顯示信息。
  • -S或--starting-file  在比較目錄時,從指定的文件開始比較。
  • -t或--expand-tabs  在輸出時,將tab字符展開。
  • -T或--initial-tab  在每行前面加上tab字符以便對齊。
  • -u,-U或--unified=  以合并的方式來顯示文件內容的不同。

    即統一格式的輸出。在合并中也使用的是這種模式。

    例如前文提到的輸出:

  --- test1 2016-04-21 14:46:55.000000000 +0800 # 第一個文件的信息
  +++ test2 2016-04-21 14:44:55.000000000 +0800 # 第二個文件的信息
  @@ -1,11 +1,5 @@                              # 第一個文件1起11行和第二個文件1起5行
  utils
  -asfdasfdasdfasdf                             # 前面帶減號的是刪除的行
  -creverververver
  +qwefqwefqwef                                 # 帶加號的是增加的行 
  util
  -aaaaaaaaaaaa
  -aaaa
  -a
  -a
  -a
  +qsdqwefqwefqwef 
  qwerqwerqwe
  -bbbbbbbbb

第一部分是文件的信息

"---"表示變動前的文件,"+++"表示變動后的文件。

第二部分表示變動的位置

@@ -1,11 +1,5 @@

減號表示第一個文件,后面的表示第一行起一共11行。加號表示第二個文件。后面是第一行起一共5行。

接下來的表示區別的部分。

  • v或--version  顯示版本信息。
  • -w或--ignore-all-space  忽略全部的空格字符。
  • -W或--width  在使用-y參數時,指定欄寬。
  • -x或--exclude  不比較選項中所指定的文件或目錄。
  • -X或--exclude-from  您可以將文件或目錄類型存成文本文件,然后在=中指定此文本文件。
  • -y或--side-by-side  以并列的方式顯示文件的異同之處。

例如:

diff test1 test2 -y

將得到:

utils                                       utils
asfdasfdasdfasdf                          | qwefqwefqwef
creverververver                           <
util                                        util
aaaaaaaaaaaa                              | qsdqwefqwefqwef
aaaa                                      <
a                                         <
a                                         <
a                                         <
qwerqwerqwe                                 qwerqwerqwe
bbbbbbbbb                                 <

這種模式中

“|”表示前后2個文件內容有不同

“<”表示后面文件比前面文件少了1行內容

“>”表示后面文件比前面文件多了1行內容

  • --help  顯示幫助。
  • --left-column  在使用-y參數時,若兩個文件某一行內容相同,則僅在左側的欄位顯示該行內容。
  • --suppress-common-lines  在使用-y參數時,僅顯示不同之處。

patch命令的使用方法

patch命令的常用格式

patch [option] [origfile] [patchfile]

我們可以先用diff命令生成patch文件。然后使用patch命令將第二個文件內容修改成第一個文件的內容。

例如上述的test1和test2:

diff -ruN test1 test2 > patch.log   # 生成patch文件
patch test2 patch.log               # 利用patch文件和patch命令打補丁

之后test2的內容就會和test1內容一致了。

patch的參數

輸入選項
-p NUM --strip=NUM 去除相對路徑層次的數目
-F LINES --fuzz LINES 設置監別列數
-l --ignore-whitespace 忽略修補數據與輸入數據的跳格,空格字符
-c --context 把修補數據解譯成關聯性的差異
-e --ed 把修補數據解譯成ed指令可用的敘述文件
-n --normal 把修補數據解譯成一般性的差異
-u --unified 把修補數據解譯成一致化的差異
-N --forward 忽略修補的數據較原始文件的版本更舊,或該版本的修補數據已使用過
-R --reverse 假設修補數據是由新舊文件交換位置而產生
-i PATCHFILE --input=PATCHFILE 讀取指定的修補文件
輸出選項
-o FILE --output=FILE 設置輸出文件的名稱,修補過的文件會以該名稱存放
-r FILE --reject-file=FILE Output rejects to FILE
-D NAME --ifdef=NAME 用指定的符號把改變的地方標示出來
-m --merge Merge using conflict markers instead of creating reject files
-E --remove-empty-files 若修補過后輸出的文件其內容是一片空白,則移除該文件
-Z --set-utc 把修補過的文件更改,存取時間設為UTC
-T --set-time 此參數的效果和指定"-Z"參數類似,但以本地時間為主
--quoting-style=WORD 使用WORD引述類型顯示項目名稱,可設定值有literal,shell,shell-always,c,escape
備份和版本控制選項
-b --backup 備份每一個原始文件
--backup-if-mismatch 在修補數據不完全吻合,且沒有刻意指定要備份文件時,才備份文件
--no-backup-if-mismatch 在修補數據不完全吻合,且沒有刻意指定要備份文件時,不要備份文件
-V STYLE --version-control=STYLE 用"-b"參數備份目標文件后,備份文件的字尾會被加上一個備份字符串,這個字符串不僅可用"-z"參數變更,當使用"-V"參數指定不同備份方式時,也會產生不同字尾的備份字符串
-B PREFIX --prefix=PREFIX 設置文件備份時,附加在文件名稱前面的字首字符串,該字符串可以是路徑名稱
-Y PREFIX --basename-prefix=PREFIX 設置文件備份時,附加在文件基本名稱開頭的字首字符串
-z SUFFIX --suffix=SUFFIX 此參數的效果和指定"-B"參數類似,差別在于修補作業使用的路徑與文件名若為src/linux/fs/super.c,加上"backup/"字符串后,文件super.c會備份于/src/linux/fs/backup目錄里
-g NUM --get=NUM 設置以RSC或SCCS控制修補作業
其他選項
-t --batch 自動略過錯誤,不詢問任何問題
-f --force 此參數的效果和指定"-t"參數類似,但會假設修補數據的版本為新版本
-s --quiet或--silent 不顯示指令執行過程,除非發生錯誤
--verbose 顯示詳細的過程信息
--dry-run 實際上不改變任何文件;演示講會發生什么
--posix 符合POSIX標準
-d DIR --directory=DIR 先改變工作目錄到指定的目錄
--reject-format=FORMAT Create 'context' or 'unified' rejects
--binary 以二進制方式讀寫數據
--read-only=BEHAVIOR 如何處理只讀輸入文件:“忽視”,他們是只讀的,“警告”(默認),或“失敗”
  • patch 命令(默認)使用從標準輸入讀入的源文件 < PATCHFILE ,但是使用 -i PATCHFILE 設置。
  • 源文件包含由 diff 命令產生的差別列表(或者 diff 列表)。差異列表是比較兩個文件和構建關于如何糾正差別的指示信息的結果。
  • 差異列表有三種格式:正常、上下文或者是 ed 編輯器風格。patch 命令確定差異列表格式,除非被 -c、-e 或 -n 標志否決。
  • 默認,ORIGFILEPATCHFILE 替換。若ORIGFILE(原始文件)不存在時,PATCHFILE(補丁文件)根據差別列表,創建 ORIGFILE 文件。
  • 指定 -b 標志時,ORIGFILE(原始文件)會備份在自身的文件中,只是在文件名后附加了后綴 .orig。使用 -o 標志也可以指定輸出的目的地。

svn diff生成的patch也可以用于更新文件

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Tcp/IP通信也是不安全的,在傳輸的時候也可能出現漏洞 查看正在運行的進程 adb shell ps -A |g...
    遠遠飄著云閱讀 4,587評論 0 0
  • 功能 給 文件1 應用補丁文件變成另外一個 文件2 (需要先用 diff 文件1 文件2 生成補丁文件)。 舉例 ...
    QuietHeart閱讀 788評論 0 1
  • diff [選項] file1 file2 功能 該命令的功能為逐行比較兩個文本文件,列出其不同之處。它比 com...
    QuietHeart閱讀 286評論 0 3
  • (一)基本命令 命令格式: 命令 參數 1.ls 顯示文件名,等同于dos下dir命令 命令格式:ls [opti...
    飛羽孟德閱讀 1,962評論 0 3
  • 主要從四個方面學習patch 什么是patch如何制作patch如何使用patchpatch的應用場景 什么是pa...
    狗錢偷生閱讀 10,879評論 0 4