Linux 的 diff 命令
?
讀懂 diff:http://www.ruanyifeng.com/blog/2012/08/how_to_read_diff.html
菜鳥教程:https://www.runoob.com/linux/linux-comm-diff.html
diff 命令詳解:https://www.cnblogs.com/wf-linux/p/9488257.html
http://man.linuxde.net/diff
https://www.cnblogs.com/everest33Tong/p/6868654.html
?
Linux diff (diff 即 different 簡寫)命令用于比較文件的差異。
diff 以逐行的方式,比較文本文件的異同處。如果指定要比較目錄,則diff會比較目錄中相同文件名的文件,但不會比較其中子目錄
?
diff file_1 file_2? diff 就會告訴你,這兩個文件有何差異。它的顯示結果不太好懂,下面我就來說明,如何讀懂diff。
?
參數:
-<行數>:指定要顯示多少行的文本。此參數必須與-c或-u參數一并使用; -a或--text:diff預設只會逐行比較文本文件; -b或--ignore-space-change:不檢查空格字符的不同; -B或--ignore-blank-lines:不檢查空白行; -c:顯示全部內容,并標出不同之處; -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=<列數>:以合并的方式來顯示文件內容的不同; -v或--version:顯示版本信息; -w或--ignore-all-space:忽略全部的空格字符; -W<寬度>或--width<寬度>:在使用-y參數時,指定欄寬; -x<文件名或目錄>或--exclude<文件名或目錄>:不比較選項中所指定的文件或目錄; -X<文件>或--exclude-from<文件>;您可以將文件或目錄類型存成文本文件,然后在=<文件>中指定此文本文件; -y或--side-by-side:以并列的方式顯示文件的異同之處; --help:顯示幫助; --left-column:在使用-y參數時,若兩個文件某一行內容相同,則僅在左側的欄位顯示該行內容; --suppress-common-lines:在使用-y參數時,僅顯示不同之處。?
?
diff 的 三種格式
?
由于歷史原因,diff 有三種格式:
我們依次來看。
?
?
示例文件
?
為了便于講解,先新建兩個示例文件。
第一個文件叫做 f1,內容是每行一個 a,一共 7 行。
a a a a a a a第二個文件叫做 f2,修改 f1 而成,第 4 行變成 hello,其他不變
a a a hello a a a?
?
正常格式的 diff
?
diff命令的Normal模式,這也是diff命令的默認模式,也就是說diff兩個文件的時候如果不加模式參數則是默認模式進行比較,其效果與(--normal)一樣,我們舉一些例子來說明Normal模式下的輸出結果(前面已經說明了一種比較結果),為了直觀查看兩個文件的不同我在windows下面通過BeyondCompare工具列出兩個文件的不同,而截圖下面的黑色部分則是diff的比較輸出截圖。
第一個文件比第二個文件少了行的情況:
第一個文件比第二個文件多出行的情況:
第一個文件與第二個文件不相同的情況:
以上 diff 命令執行的時候沒有指定額外的模式參數,所以其使用的是默認的 Normal 模式,效果與添加命令行參數 --normal 是一樣的。
?
使用示例分析
現在對 f1 和 f2 進行比較:$ diff f1 f2
這時,diff 就會顯示正常格式的結果:
4c4< a---> hello?
?
上下文格式的 diff :Context 模式
?
上個世紀80年代初,加州大學伯克利分校推出 BSD版本的 Unix 時,覺得 diff 的顯示結果太簡單,最好加入上下文,便于了解發生的變動。因此,推出了上下文格式的 diff。
默認情況下的模式輸出結果實際上是符合計算機的思維方式,不太直觀,所以其輸出結果并不能夠很好的被人理解,diff命令除了默認模式之外還提供了另外兩種模式,Context 和 Unified 模式。
diff 命令應用 Context 模式只需要添加命令行參數 diff -c? 即可,我們先看看兩個案例文件:
接下來說明這兩個文件以diff? -c 方式比較的結果:
?
使用示例分析
上下文模式 使用方法加入 c 參數(代表context):$ diff -c f1 f2
顯示結果如下:
$ diff -c f1 f2 *** f1 2019-05-20 14:22:15.111801433 +0800 --- f2 2019-05-20 14:22:27.401207382 +0800 *************** *** 1,7 ****aaa ! aaaa --- 1,7 ----aaa ! helloaaa這個結果分成四個部分。
????????*** f1????2019-05-20 14:22:15.111801433 +0800
????????--- f2????2019-05-20 14:22:27.401207382 +0800
提示:"***" 表示變動前的文件,"---" 表示變動后的文件。
***************
*** 1,7 ****
?a
?a
?a
!a
?a
?a
?a
這時不僅顯示發生變化的第 4 行,還顯示第 4 行的前面三行和后面三行,因此一共顯示7行。所以,前面的"*** 1,7 ****"就表示,從第 1 行開始連續 7 行。
另外,文件內容的每一行最前面,還有一個標記位。
如果為空,表示該行無變化;
如果是感嘆號(!),表示該行有改動;
如果是減號(-),表示該行被刪除;
如果是加號(+),表示該行為新增。
第四部分顯示變動后的文件,即f2。
--- 1,7 ----
?a
?a
?a
!hello
?a
?a
?a
除了變動行(第4行)以外,也是上下文各顯示三行,總共顯示7行。
?
?
合并格式的 diff:也即 Unified 模式
?
如果兩個文件相似度很高,那么上下文格式的 diff,將顯示大量重復的內容,很浪費空間。1990年,GNU diff 率先推出了"合并格式"的 diff,將 f1 和 f2 的上下文合并在一起顯示。
diff 還有一種比較方式,也即 Unified 模式,使用命令行 –u 來執行該模式的比較。其比較結果與Context模式很像,但是簡化了一些輸出,我們看看我們的案例文件,與上面的一樣:
使用diff –u 比較的結果:
可以看到其比較結果與Context模式實際上差不多,只不過將比較結果合并到一起了
?
使用示例分析
加入u參數(代表unified):$ diff -u f1 f2
顯示結果如下:
$ diff -u f1 f2 --- f1 2019-05-20 14:22:15.111801433 +0800 +++ f2 2019-05-20 14:22:27.401207382 +0800 @@ -1,7 +1,7 @@aaa -a +helloaaa第一部分,也是文件的基本信息。
? ? ? ? ? ? --- f1?? ?2019-05-20 14:22:15.111801433 +0800
? ? ? ? ? ? +++ f2?? ?2019-05-20 14:22:27.401207382 +0800
? ? ? ? ? ? "---"表示變動前的文件,"+++"表示變動后的文件。
第二部分,變動的位置用兩個@作為起首和結束。
? ? ? ? ? ? @@ -1,7 +1,7 @@
? ? ? ? ? ? 前面的"-1,7"分成三個部分:減號表示第一個文件(即f1),"1"表示第1行,"7"表示連續7行。合在一起,就表示下面是第一個文件從第1行開始的連續7行。
? ? ? ? ? ? 同樣的,"+1,7"表示變動后,成為第二個文件從第1行開始的連續7行。
第三部分,是變動的具體內容。
?a
?a
?a
-a
+hello
?a
?a
?a
除了有變動的那些行以外,也是上下文各顯示3行。它將兩個文件的上下文,合并顯示在一起,所以叫做"合并格式"。
每一行最前面的標志位,空表示無變動,減號表示第一個文件刪除的行,加號表示第二個文件新增的行。
?
?
git 格式的 diff
?
版本管理系統git,使用的是合并格式 diff 的變體:$ git diff
顯示結果如下:
? ? ? ? diff --git a/f1 b/f1index 6f8a38c..3235643 100644--- a/f1+++ b/f1@@ -1,7 +1,7 @@aaa-a+helloaaa第一行 表示結果為 git 格式的diff。
? ? diff --git a/f1 b/f1
? ? 進行比較的是,a版本的f1(即變動前)和b版本的f1(即變動后)。
第二行 表示兩個版本的 git 哈希值(index區域的6f8a38c對象,與工作目錄區域的449b072對象進行比較),最后的六位數字是對象的模式(普通文件,644權限)。
? ? index 6f8a38c..449b072 100644
第三行 表示進行比較的兩個文件。
--- a/f1
+++ b/f1
"---"表示變動前的版本,"+++"表示變動后的版本。
后面的行都與官方的合并格式diff相同。
@@ -1,7 +1,7 @@
?a
?a
?a
-a
+hello
?a
?a
?a
?
?
比較目錄
?
使用diff可以比較兩個目錄,其比較格式是? diff? directory1? directory2 查看如下目錄比較結果:
比較兩個目錄的時候無非是有的文件僅僅存在于某個目錄中而在另一個目錄中沒有,如果存在同名的文件,則比較這兩個文件的不同。diff比較目錄的結果我們可以結合grep命令篩選出我們想要的輸出,例如僅僅輸出兩個目錄下不同的文件而忽略掉某一個目錄獨有另一個目錄不存在的輸出記錄
?
?
?
實例1:比較兩個文件
[root@localhost test3]# diff log2014.log log2013.log 3c3 < 2014-03 --- > 2013-03 8c8 < 2013-07 --- > 2013-08 11,12d10 < 2013-11 < 2013-12上面的"3c3"和"8c8"表示log2014.log和log20143log文件在3行和第8行內容有所不同;"11,12d10"表示第一個文件比第二個文件多了第11和12行。
?
實例2:并排格式輸出
[root@localhost test3]# diff log2014.log log2013.log -y -W 50 2013-01 2013-01 2013-02 2013-02 2014-03 | 2013-03 2013-04 2013-04 2013-05 2013-05 2013-06 2013-06 2013-07 2013-07 2013-07 | 2013-08 2013-09 2013-09 2013-10 2013-10 2013-11 < 2013-12 < [root@localhost test3]# diff log2013.log log2014.log -y -W 50 2013-01 2013-01 2013-02 2013-02 2013-03 | 2014-03 2013-04 2013-04 2013-05 2013-05 2013-06 2013-06 2013-07 2013-07 2013-08 | 2013-07 2013-09 2013-09 2013-10 2013-10> 2013-11> 2013-12說明:
- "|"表示前后2個文件內容有不同
- "<"表示后面文件比前面文件少了1行內容
- ">"表示后面文件比前面文件多了1行內容
?
?
?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Linux 的 diff 命令的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux下查看系统版本号信息的方法
- 下一篇: 小甲鱼 OllyDbg 教程系列 (十五