linux命令diff

diff 命令是 Linux 上很是重要的工具,用於比較文件甚至目錄的內容,清晰的告訴你先後改動的地方。diff 能夠輸出爲補丁(patch) ,Linux 中還有一條命令patch,能夠根據補丁文件,對文件更新修改。當你和別人合做或想爲開源項目提供貢獻時,能夠將本身的修改打成補丁,郵件給合做者,他便可合併你的代碼。所以diff也是svn、cvs、git等版本控制工具不可或缺的一部分。 git

diff

diff的基本格式以下: github

$ diff [參數] <變更前的文件> <變更後的文件>

命令參數有如下經常使用的一些,能夠根據不一樣的模式選用: vim

-b 或--ignore-space-change     不檢查空格字符的不一樣。
-B 或--ignore-blank-lines      不檢查空白行。
-w 或--ignore-all-space        忽略所有的空格字符。
-i 或--ignore-case             不檢查大小寫的不一樣。
-q 或--brief                   僅顯示有無差別,不顯示詳細的信息。

在diff目錄時經常使用的參數以下: svn

-r 或--recursive               比較子目錄中的文件。
-N 或--new-file                文件A僅出如今某個目錄中,預設會顯示:Only in目錄
                                文件A若使用-N參數,則diff會將文件A與一個空白的文件比較。
-P或--unidirectional-new-file  與-N相似,只有當第二個目錄包含了一個第一個目錄所沒有的文件時,
                                纔會將這個文件與空白的文件作比較。

diff有大概四種格式:正常格式並列格式上下文格式合併格式工具

還有git diff與vimdiff模式。 ui

diff能夠比較文本文件或目錄之間的差別,首先來說解文本文件之間的diff,示例文件以下: spa

文件f1 插件

a b
b
c
d
e

文件f2 3d

a b c
b
d
e
f

正常格式diff

正常格式不用加任何參數,diff f1 f2便可,顯示結果以下: 版本控制

1c1
< a b
---
> a b c
3d2
< c
5a5
> f

1c一、3d二、5a5是說明變更的位置,前邊數字表明f1中變化的行,後邊的則表明f2中變化的行,中間的字母分別表明「改變」(c)、「刪除」(d)和「增長」(a)。

<表示f1指定行的內容,---分割兩個文件的,而後>表示f2指定行的內容。刪除或增長時,則分別f二、f1中指定行無內容。

並列格式diff

其餘格式diff都是前後顯示兩個文件的內容變化,並列格式能夠並排顯示兩個文件的內容變化,更形象的看出文件的變化,和vimdiff顯示的有些類似。

使用方法爲加入-y參數,便可並列顯示,-W num參數可設定並列的寬度,能夠不使用。

diff -y -W 50 f1 f2

結果以下:

a b                   | a b c
b                       b
c                     <
d                       d
e                       e
                      > f

|說明此行有變化,<說明此行被刪除了,>說明此行是後增長的。

上下文格式diff

標準格式diff顯示的內容不夠直觀,上下文格式則經過顯示變化的上下文,而更加的利於理解。

使用方法爲使用參數-c參數: diff -c f1 f2,結果以下:

*** f1  2014-04-03 21:24:23.581007082 +0800
--- f2  2014-04-03 21:24:21.324995895 +0800
***************
*** 1,5 ****
! a b
  b
- c
  d
  e
--- 1,5 ----
! a b c
  b
  d
  e
+ f

首先,顯示兩個文件的基本狀況:

*** f1  2014-04-03 21:24:23.581007082 +0800
--- f2  2014-04-03 21:24:21.324995895 +0800

***表示變更前的文件f1,---表示變更後的文件f2。

而後,15個星號將文件的基本狀況與變更內容分割開。

最後,顯示f1和f2文件的內容變更狀況。

*** 1,5 ****表示f1文件的1~5行

--- 1,5 ----表示f2文件的1~5行

!表明次行內容有變更,+表示此行爲新增長,-表示此行被刪除了。

上下文格式默認顯示包括修改行先後的三行內容,可使用-num來設置顯示先後num行,如:

diff -c -1 f1 f2

合併格式diff

兩個文件大量內容重複,上下文格式將顯示不少無用干擾信息,後來就退出了合併式diff。

使用方法爲,加入-u參數,diff -u f1 f2,結果以下:

--- f1  2014-04-03 21:24:23.581007082 +0800
+++ f2  2014-04-03 21:24:21.324995895 +0800
@@ -1,5 +1,5 @@
-a b
+a b c
 b
-c
 d
 e
+f

一樣前兩行表示兩個文件的基本狀況

而後@@ -1,5 +1,5 @@表示修改的位置,-表明 f1 的1~5行,+表明 f2 的1~5行。

最後是合併顯示的變更具體內容,依舊是-表明f1,+表明f2。

同上下文格式同樣,合併格式也是默認顯示修改先後3行的內容,也可使用-num來設置顯示先後num行:

diff -u -1 f1 f2

這裏還要提到,git使用的是合併格式diff的變體。當前工做目錄下git add f1後,修改f1的內容,可使用以下命令,觀察作出的修改

git diff

結果以下:

diff --git a/f1 b/f1
index 924a897..c3b09ff 100644
--- a/f1
+++ b/f1
@@ -1,5 +1,5 @@
-a b
+a b c
 b
-c
 d
 e
+f

和合並格式diff的區別在頭部文件基本信息,git diff顯示的是a、b兩個版本的f1文件的內容變化,而且顯示了兩個版本的git哈希值(924a897..c3b09ff),與文件的權限(644)。

vimdiff

Vim提供的diff模式稱做imdiff,能夠很清晰形象的觀察到文件內容的變化,方便的進行合併工做。vimdiff的使用方法以下:

vimdiff f1 f2
或者
vim -d f1 f2

下圖爲結果的畫面

vimdiffvimdiff

默認屏幕垂直分割,對比顯示兩個文件的不一樣,若是想要水平分割可使用參數-o(不過怎麼也是垂直的好看)。這裏能夠看到f1和f2中都有的可是內容改變的行被高亮爲紅色,次行內修改的具體位置被高亮爲黃色;f1裏有可是在f2中被刪除的行,f1中顯示爲藍色,f2中顯示爲綠色;相反,f2中增長的行顯示爲藍色,f1中相應位置顯示爲綠色。這樣更突出引發差別的地方,而且若是文件內容較多,連續相同的行會摺疊起來,可使用zo和zc打開和關閉摺疊。

對不一樣修改內容的高亮顯示,顏色能夠本身自定義,在本身的Vim配置文件~/.vimrc中添加以下語句:

hi DiffAdd ctermbg=blue ctermfg=white
hi DiffDelete ctermbg=green ctermfg=none
hi DiffChange ctermbg=red ctermfg=White
hi DiffText ctermbg=yellow ctermfg=black

使用GUI的話能夠配置guibg和guifg。

切換不一樣的窗口可使用下列命令:

Ctrl-w l        切換到右邊窗口
Ctrl-w h        切換到左邊窗口
Ctrl-w j        切換到下邊窗口
Ctrl-w k        切換到上邊窗口

在編輯文件時也可使用命令模式啓動vimdiff模式:

vim f1
:vertical diffsplit f2

若是不加vertical默認使用的水平分割。在Vim中除了diffsplit還有一些其餘的命令,利於對文件進行合併和其餘操做。

:diffget        把差別點中另外一個文件對應的內容複製到當前行
:diffput        把差別點中當前行的內容複製到另外一個文件對應的位置
:diffpatch      根據補丁文件更新文件內容,後面須要跟一個參數指定文件
:diffupdate     手動刷新比較結果

:qa             同時退出兩個文件
:wqa            同時保存並退出

若是Vim安裝來vim-fugitive插件,還可使用:Gdiff命令來比較當前文件和暫存區中的文件的不一樣,也是利用的vimdiff,顯示和操做同上。

目錄的diff

目錄間的diff比較目錄中相同文件名的文件,也可使用正常格式、上下文格式、合併格式、並列格式。

示例目錄爲d1和d2目錄,d1中有文件f一、f3,d2中有f一、f2,其中f1有一些改動。

若是不是用其餘參數,不會遞歸比較子目錄中的文件,會顯示只存在目錄一個目錄中的文件,但不顯示其詳細信息,以下結果是使用diff -u d1 d2的結果:

diff -u d1/f1 d2/f1
--- d1/f1   2014-04-03 19:29:25.910803383 +0800
+++ d2/f1   2014-04-03 19:28:52.918639783 +0800
@@ -1,5 +1,5 @@
-a b c
+a b
b
+c
d
e
-f
只在 d2 存在:f2
只在 d1 存在:f3

在目錄的diff中常使用的參數是-ruN,r表示遞歸比較子目錄中的文件,u是合併格式,N表示diff會將只存在與某個目錄中的文件與一個空白的文件比較。

patch

將diff的輸出重定向到文本文件中,即獲得補丁文件(patch),可使用patch命令對文本文件或目錄打補丁,從而進行內容更新。

patch的基本用法

patch [參數] <patchfile>

參數:

-p Num  忽略幾層文件夾
-E      選項說明若是發現了空文件,那麼就刪除它
-R      取消打過的補丁。

若是使用參數-p0,表示從當前目錄找打補丁的目標文件夾,再對該目錄中的文件執行patch操做。 而使用參數-p1,表示忽略第一層目錄,從當前目錄尋找目標文件夾中的子目錄和文件,進行patch操做。

處理單個文件補丁

產生補丁

diff -uN f1 f2 > file.patch

打補丁

patch -p0 < file.patch
或者
patch f1 file.patch

取消補丁

patch -RE -p0 < file.patch
或者
patch -RE f1 file.patch

處理目錄補丁

產生補丁

diff -urN d1 d2 > dir.patch

打補丁

cd d1
patch -p1 < ../dir.patch

取消補丁

patch -R -p1 < ../dir.patch

應用補丁時的目標代碼和生成補丁時的代碼未必相同,打補丁操做可能失敗,補丁失敗的文件會以.rej結尾。

相關文章
相關標籤/搜索