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 標志否決。
- 默認,ORIGFILE 被PATCHFILE 替換。若ORIGFILE(原始文件)不存在時,PATCHFILE(補丁文件)根據差別列表,創建 ORIGFILE 文件。
- 指定 -b 標志時,ORIGFILE(原始文件)會備份在自身的文件中,只是在文件名后附加了后綴 .orig。使用 -o 標志也可以指定輸出的目的地。
svn diff生成的patch也可以用于更新文件