鍍金池/ 教程/ Linux/ shell 學(xué)習(xí)四十七天----文件比較 cmp,diff,patch
shell 學(xué)習(xí)四十一天----列出文件 ls 和 od 命令
shell 學(xué)習(xí)小結(jié)
shell 學(xué)習(xí)第二十八天----case 語句
shell 學(xué)習(xí)四十四天----尋找文件
shell 學(xué)習(xí)三十五天----波浪號展開與通配符
shell 學(xué)習(xí)三十八天----執(zhí)行順序和 eval
shell 學(xué)習(xí)四十八天----文件校驗和匹配
shell 學(xué)習(xí)四十天----awk 的驚人表現(xiàn)
shell 學(xué)習(xí)第十一天----sed 正則的精確控制
shell 學(xué)習(xí)第十七天----awk 命令
shell 學(xué)習(xí)三十九天----內(nèi)建命令
shell 學(xué)習(xí)四十五天----xargs
shell 學(xué)習(xí)三十七天----引用
shell 學(xué)習(xí)第十六天----join 練習(xí)
shell 學(xué)習(xí)第二十四天----提取開頭或結(jié)尾數(shù)行
shell 學(xué)習(xí)第九天----分組
shell 學(xué)習(xí)第五天----基本的 I/O 重定向
shell 學(xué)習(xí)第十五天----使用 cut 選定字段
shell 學(xué)習(xí)四十六天----文件系統(tǒng)的空間信息 df 和 du 命令
shell 學(xué)習(xí)第八天----擴展正則表達式 (ERE)
shell 學(xué)習(xí)第十九天----文本塊排序
shell 學(xué)習(xí)第二十一天----重新格式化段落
shell 學(xué)習(xí)三十六天----命令替換
shell 學(xué)習(xí)第二十天----sort 的其他內(nèi)容以及 uniq 命令
shell 學(xué)習(xí)四十二天----使用 touch 更新文件時間
shell 學(xué)習(xí)五十一天----top 命令查看進程列表
shell 學(xué)習(xí)第一天
shell 學(xué)習(xí)五十四天----進程系統(tǒng)調(diào)用的追蹤 strace
shell 學(xué)習(xí)五十天----查看進程 ps 命令
shell 學(xué)習(xí)第二十七天----退出狀態(tài)和 if 語句
shell 學(xué)習(xí)第二十三天----打印
shell 學(xué)習(xí)三十三天----關(guān)于重定向
shell 學(xué)習(xí)四十九天----進程建立
shell 學(xué)習(xí)第三十天----break,continue,shift,getopts
shell 學(xué)習(xí)五十五天----進程記賬
shell 學(xué)習(xí)總結(jié)一
shell 學(xué)習(xí)第二十六天----變量與算數(shù)
shell 學(xué)習(xí)第二十二天----計算行數(shù), 字?jǐn)?shù)以及字符數(shù)
shell 學(xué)習(xí)五十八天----/proc 文件系統(tǒng)
shell 學(xué)習(xí)第二十五天----神器的管道符
shell 學(xué)習(xí)第三十二天----read 讀取一行
sheel 學(xué)習(xí)第三天
shell 學(xué)習(xí)----小結(jié)
shell 學(xué)習(xí)第十八天----文本排序
shell 學(xué)習(xí)第三十一天----函數(shù)問題
shell 學(xué)習(xí)第十天----sed 查找與替換
shell 學(xué)習(xí)四十三天----臨時性文件的建立與使用
shell 學(xué)習(xí)四十七天----文件比較 cmp,diff,patch
shell 學(xué)習(xí)三十四天----printf 詳解
shell 學(xué)習(xí)五十七天 ----linux 任務(wù)管理,針對上一講的總結(jié)和擴展
shell 學(xué)習(xí)第六天----小結(jié)
shell 學(xué)習(xí)第十三天----sed 案例分析
shell 學(xué)習(xí)第七天----基礎(chǔ)正則表達式 (BRE)
shell 學(xué)習(xí)第十二天----行與字符串
shell 學(xué)習(xí)小結(jié)四
shell 學(xué)習(xí)第二十九天----循環(huán)
shell 學(xué)習(xí)五十二天----刪除進程 kill 命令
shell 學(xué)習(xí)五十六天----延遲進程調(diào)度
shell 學(xué)習(xí)第四天----華麗的 printf 輸出
shell 學(xué)習(xí)第十五天----join 連接字段
shell 學(xué)習(xí)完結(jié)篇----希望你能看到
shell 學(xué)習(xí)第二天
shell 學(xué)習(xí)五十三天----捕獲信號 trap

shell 學(xué)習(xí)四十七天----文件比較 cmp,diff,patch

文件比較

所謂的文件比較,一般設(shè)計四個領(lǐng)域

  1. 檢查兩個文件是否相同,如果不同,找不哪里不同
  2. 應(yīng)用兩個文件的不同之處,使從其中一個回復(fù)另外一個
  3. 使用校驗和找出相同一致的文件
  4. 使用數(shù)字簽名以驗證文件

cmp 和 diff

在文字處理上,最常出現(xiàn)的問題應(yīng)該是比較兩個或兩個以上的文件,看看他們的內(nèi)容是否相同 ---- 即便它們的名稱不同。

案例: ```$cp /bin/ls /tmp/ls #制作 /bin/ls 的私用副本 $cmp /bin/ls /tmp/ls #拿原始文本與副本比較 \ $cmp /bin/cp /tmp/ls #輸出結(jié)構(gòu)指出第一個不同處的位置 /bin/cp /tmp/ls differ:byte 25,line 1


分析:   
cmp 發(fā)現(xiàn)兩個參數(shù)文件一致時,會采用默認(rèn)的方式。如果你只對他的離開狀態(tài)有興趣,可以使用 -s 選項,抑制警告信息:

- `$cmp -s /bin/cp /tmp/ls       #默認(rèn)的比較兩文件的不同`
- `$echo $? #顯示離開碼`
- `1 #非 0,表示兩個文件不同`

**cmp 命令詳解**

語法:
`cmp [選項] [文件]`

主要選項:

- `-c`
除了標(biāo)明差異處的十進制字碼之外,一并顯示該字符所對應(yīng)字符。
- `-i< 字符數(shù)目 >` 
制定一個數(shù)目
- `-l`
顯示出所有不一樣的地方
- `-s`
不顯示錯誤的信息
- `-v`
顯示版本信息
注意:在比較結(jié)果中,只能夠西顯示第一個不同的比較結(jié)果。

如果你想知道兩個文件有何不同,可使用 `diff`,`diff` 命令是 linux 上非常重要的命令,用于比較文件的內(nèi)容,特別是比較兩個版本不同的文件以找到改動的地方。`diff` 在命令行中打印每一行的改動。最新版本的 `diff` 還支持二進制文件。`diff` 程序的輸出被稱為補丁 (patch),因為 linux 系統(tǒng)中海油一個 patch 程序,可以根據(jù) `diff` 的輸出將 `a.c` 的文件內(nèi)容更新為 `b.c` 。`diff` 是 svn,cvs,git 等版本控制工具不可獲取的一部分。

**diff 命令詳解**

語法:  
diff [選項] [變動前文件或目錄] [變動后文件或目錄]

功能:  
比較單個文件或目錄的內(nèi)容。如果指定比較的是文件,則只有當(dāng)輸入為文本文件時才有效。以逐行的方式,比較文本文件的異同處。如果指定比較的是目錄,diff 命令會比較兩個目錄下名字相同的文本文件。列出不同的二進制文件,公共子目錄和只在一個目錄出現(xiàn)的文本。

主要選項:  

- `-b`
不檢查空格字符的不同
- `-B`
不檢查空白行
- `-w`
忽略全部的空格字符
- `-i`
不檢查大小寫的不同
- `-q`
僅顯示有無差異,不顯示詳細(xì)的信息

在 diff 目錄時常用的參數(shù)如下:

- `-r`
比較子目錄中的文件
- `-N`
文件 A 僅出現(xiàn)在某個目錄中,預(yù)設(shè)會顯示:only in 目錄,文件 A 若使用 `-N` 參數(shù),則 `diff` 會將文件 A 與一個空白的文件比較
- `-P`
與 `-N` 類似,只有當(dāng)?shù)诙€目錄包含了一個第一個目錄所沒有的文件時,才會將這個文件與空白的文件作比較。

diff 有四種格式:

1. 正常格式
2. 并列格式
3. 上下文格式
4. 合并格式

正常格式案例:不添加任何參數(shù)

$cat f1 a b b c d e $cat f2 a b c b d e f 1c1 \< a b --- > a b c 3d2 \< c 5a5 > f


分析:

- `1c1`,`3d2`,`5a5` 是說明變動的位置,前邊數(shù)字代表 f1 中國所變化的行,后面的則代表 f2 中變化的行,中間的字母分別代表 “改變 (c)”,“刪除 (d)” 和 “增加 (a)”

- `<` 表示 f1 指定行的內(nèi)容,--- 分割兩個文件的,然后 `>` 表示 f2 指定行的內(nèi)容。刪除或增加時,則分別 f2,f1 中指定行無內(nèi)容

**并列格式 diff**

其他格式 diff 都實現(xiàn)后顯式兩個文件的內(nèi)容變化,并列格式可以并排顯式兩個文件的內(nèi)容變化,更形象的看出文件的變化,和 `vimdiff` 顯式的有些類似。

使用方法為加入 `-y` 選項,即可并列顯示,`-W(大寫) num` 參數(shù)可設(shè)定并列的寬度,可以不使用。

$ diff -y -W 50 f1 f2 a b | a b c b b c < d d e e

f

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

上下文格式 diff

標(biāo)準(zhǔn)格式 diff 顯式的內(nèi)容不夠直觀,上下文格式則通過顯示變化的上下文,而更加的利與理解。 使用方法是使用參數(shù) -c。

案例:

$diff -c f1 f2
\*** f1  2015-07-13 18:42:50.996380933 +0800
\--- f2  2015-07-13 18:43:06.846375746 +0800
\***************
\*** 1,5 ****
! a b
  b
- c
  d
  e
\--- 1,5 ----
\! a b c
  b
  d
  e
\+ f

分析:

  • 首先,顯示兩個文件的基本情況: *** f1 2015-07-13 18:42:50.996380933 +0800 --- f2 2015-07-13 18:43:06.846375746 +0800 *** 表示變動前的文件 f1,--- 表示變動后的文件 f2
  • 然后 15 個星號將文件的基本情況和變動內(nèi)容分隔開 *** 1,5 **** 表示 f1 文件的 1-5 行 --- 1,5 ---- 表示 f2 文件的 1-5 行
  • ! 代表此行內(nèi)容有變動,+ 表示新增加的,- 表示此行被刪除了。
  • 上下文格式默認(rèn)顯示包括修改行前后的三行內(nèi)容,可以使用 -num 來設(shè)置前后 num 行,如: $diff -C(大寫 C) -1(數(shù)字 1) f1 f2

合并格式 diff

兩個文件大量內(nèi)容重復(fù),上下文格式顯示很多無用的干擾信息,后來就推出了合并式 diff。 使用方法為,加入 -u 參數(shù),案例:
$diff -u f1 f2 diff -u f1 f2 --- f1 2015-07-13 18:42:50.996380933 +0800 +++ f2 2015-07-13 18:43:06.846375746 +0800 @@ -1,5 +1,5 @@ -a b +a b c b -c d e +f

分析:

  • 同樣前兩行表示兩個文件的基本情況
  • 然后 @@-1,5 +1,5 @@表示修改的位置,- 代表 f1 的 1-5 行,+ 代表 f21-5 行。
  • 最后是合并顯示的變動具體內(nèi)容,依舊是 - 代表 f1,+ 代表 f2。 同上下文格式一樣,合并格式也是默認(rèn)顯示修改前后三行的內(nèi)容,可以使用 -num 來設(shè)置顯示前后 num 行: $diff -u -1 f1 f2

patch 工具程序

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

patch 詳解

語法: patch [選項] [補丁文件]

主要參數(shù):

  • -p num 忽略幾層文件夾
  • -E 選項說明如果發(fā)生了空文件,那么就刪除它
  • -R 取消打過的補丁

如果使用參數(shù) -p0,表示從當(dāng)前目錄找打補丁的目標(biāo)文件夾,再對該目錄中的文件執(zhí)行 patch 操作。 而是用參數(shù) -p1,表示忽略第一層目錄,從當(dāng)前目錄需找目標(biāo)文件夾中的子目錄的文件,進行 patch 操作。

處理單個文件補丁

產(chǎn)生補丁: $diff -uN f1 f2 > file.patch

打補?。?$patch -p0 <file.patch 或者 $patch f1 file.patch

取消補丁: $patch -RE -p0 < file.patch 或者 $patch -RE f1 file.patch

處理文件補丁

產(chǎn)生補?。?$diff -urN d1 d2 > dir.patch

打補?。?$cd d1 $patch -p1 < ../dir.patch

取消補?。?patch -R -p1 < ../dir.patch

應(yīng)用補丁時的目標(biāo)代碼和生成補丁時的代碼未必相同,打補丁的操作可能失敗,補丁失敗的文件會以.rej 結(jié)尾。

patch 工具程序可利用 diff 輸出,結(jié)合原始文件,以重建另一個文件,因為相異的部分,通常比原始文件小得多,軟件開發(fā)人員常會通過 email 交換相異處的列表,再使用 patch 應(yīng)用它。

雖然 patch 可使用 diff 的一半輸出,但較通用的當(dāng)時影視使用 diff 的 -c 選項,已取得上下文差異處。這么做會產(chǎn)生較詳細(xì)冗長的報告,rangpatch 知道文件名,允許他驗證變更位置,并回復(fù)不同之處。如果兩個文件自從差異出已被記錄下來之后都未有修改,則上下文差異功能是不重要的,但是在軟件開發(fā)中,時常會有其中之一牽涉其中。不難看出 patch 的作用就是為了高效的就留程序源代碼產(chǎn)生的,patch 只包含了對源代碼修改的部分。