1. 程式人生 > >Shell命令-文件及內容處理之diff、vimdiff

Shell命令-文件及內容處理之diff、vimdiff

text 屏幕滾動 就是 大文件 如同 創建 == --help The

文件及內容處理 - diff、vimdiff

1. diff:比較兩個文件區別

diff命令的功能說明

diff命令用比較文件的差異。diff以逐行的方式,比較文本文件的異同處。如果指定要比較目錄,則diff會比較目錄中相同文件名的文件,但不會比較其中子目錄。

diff命令的語法格式

diff [-abBcdefHilnNpPqrstTuvwy][-<行數>][-C <行數>][-D <巨集名稱>][-I <字符或字符串>][-S <文件>][-W <寬度>][-x <文件或目錄>][-X <文件>][--help][--left-column][--suppress-common-line][文件或目錄1][文件或目錄2]
diff [參數選項] [兩個文件]

diff命令的選項說明

diff 選項很多,但是用的不多,表1為 diff 命令的參數及說明:

表1: 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命令的實踐操作

範例1: 備份 /etc/passwd,然後修改源文件,然後通過 diff 命令進行比較

--------------------------------------------------------------
==>備份/etc/passwd<==
--------------------------------------------------------------
[[email protected]  ~]# cp /etc/passwd{,.ori}

--------------------------------------------------------------
==>源文件/etc/passwd添加內容<==
---------------------------------------------------------------
[[email protected]  ~]# echo 'test' >> /etc/passwd

--------------------------------------------------------------
==>查看/etc/passwd添加的內容<==
--------------------------------------------------------------
[[email protected]  ~]# tail -1 /etc/passwd
test

--------------------------------------------------------------
==>比較不同(也可以將兩個文件分開寫,要有空格)<==
--------------------------------------------------------------
[[email protected]  ~]# diff /etc/passwd{,.ori}
25d24
< test

--------------------------------------------------------------
==>25行有新加的test<==
--------------------------------------------------------------
[[email protected]  ~]# grep -n  -B3 'test' /etc/passwd
22-tcpdump:x:72:72::/:/sbin/nologin
23-nginx:x:1001:1001::/home/nginx:/sbin/nologin
24-ntp:x:38:38::/etc/ntp:/sbin/nologin
25:test

--------------------------------------------------------------
==>24行後,無內容,(過濾的內容實際而定)<==
--------------------------------------------------------------
[[email protected]  ~]# grep -n  -A10 'tcpdump' /etc/passwd.ori 
22:tcpdump:x:72:72::/:/sbin/nologin
23-nginx:x:1001:1001::/home/nginx:/sbin/nologin
24-ntp:x:38:38::/etc/ntp:/sbin/nologin

範例2: 並排格式輸出

--------------------------------------------------------------
==>創建演示文本<==
--------------------------------------------------------------
[[email protected] /test]# seq -w 10 >oldboy.txt
[[email protected] /test]# cat oldboy.txt 
01
02
03
04
05
06
07
08
09
10

--------------------------------------------------------------
==>備份源文件<==
--------------------------------------------------------------
[[email protected] /test]# cp oldboy.txt{,.ori}
[[email protected] /test]# cat oldboy.txt.ori 
01
02
03
04
05
06
07
08
09
10

--------------------------------------------------------------
==>往源文件追加內容<==
--------------------------------------------------------------
[[email protected] /test]# echo 521 >> oldboy.txt

--------------------------------------------------------------
==>並排格式輸出<==
--------------------------------------------------------------
[[email protected] /test]# diff oldboy.txt{,.ori} -y -W 50
01          01
02          02
03          03
04          04
05          05
06          06
07          07
08          08
09          09
10          10
521           <

說明:

  • | 表示前後2個文件內容有不同
  • < 表示後面文件比前面文件少了1行內容
  • > 表示後面文件比前面文件多了1行內容

2. vimdiff:快速比較和合並少量文件

vimdiff命令的功能說明

純文本文件比較和合並工具一直是軟件開發過程中比較重要的組成部分,vimdiff 能夠在比較出來的多處差異之間快速定位,很容易的進行文件合並操作。在需要快速比較和合並少量文件的時候,vimdiff 是很好的選擇。首先保證系統中的 diff 命令是可用的。Vimdiff 模式是依賴於 diff 命令的。

vimdiff命令的語法格式

vimdiff [options] file1 file2 [file3 [file4]]
vimdiff [參數選項] [兩個文件]

vimdiff命令的選項說明

vimdiff 用的不多,這裏就省略了

vimdiff命令的實踐操作

範例1: 備份 /etc/passwd,然後修改源文件,然後通過 vimdiff 命令進行比較

使用vimdiff效果如下圖所示:(vimdiff /etc/passwd /etc/passwd.ori)

技術分享圖片

從上圖我們可以看到一個清晰的比較結果。屏幕被垂直分割,左右兩側分別顯示被比較的兩個文件。兩個文件中連續的相同的行被折疊了起來,以便使用者能把註意力集中在兩個文件的差異上。只在某一文件中存在的行的背景色被設置為藍色,而在另一文件中的對應位置被顯示為綠色。兩個文件中都存在,但是包含差異的行顯示為粉色背景,引起差異的文字用紅色背景加以突出。

如果希望交換兩個窗口的位置,或者希望改變窗口的分割方式,可以使用下列命令:

  1. Ctrl-w K(把當前窗口移到最上邊)
  2. Ctrl-w H(把當前窗口移到最左邊)
  3. Ctrl-w J(把當前窗口移到最下邊)
  4. Ctrl-w L(把當前窗口移到最右邊)其中1和3兩個操作會把窗口改成水平分割方式。

光標移動

接下來試試在行間移動光標,可以看到左右兩側的屏幕滾動是同步的。這是因為 scrollbind 選項被設置了的結果,vimdiff 會盡力保證兩側文件的對齊。如果不想要這個特性,可以設置:

:set noscrollbind

可以使用快捷鍵在各個差異點之間快速移動。跳轉到下一個差異點:

]c

反向跳轉是:

[c

如果在命令前加上數字的話,可以跳過一個或數個差異點,從而實現跳的更遠。比如如果在位於第一個差異點的行輸入 2]c,將越過下一個差異點,跳轉到第三個差異點。

文件合並

文件比較的最終目的之一就是合並,以消除差異。如果希望把一個差異點中當前文件的內容復制到另一個文件裏,可以使用命令

dp (diff "put")

如果希望把另一個文件的內容復制到當前行中,可以使用命令

do (diff "get",之所以不用dg,是因為dg已經被另一個命令占用了)

如果希望手工修改某一行,可以使用通常的 vimdiff 操作。如果希望在兩個文件之間來回跳轉,可以用下列命令序列:

Ctrl-w, w

在修改一個或兩個文件之後,vimdiff 會試圖自動來重新比較文件,來實時反映比較結果。但是也會有處理失敗的情況,這個時候需要手工來刷新比較結果:

:diffupdate

如果希望撤銷修改,可以和平常用 vim 編輯一樣,直接

<ESC>, u

同時操作兩個文件

在比較和合並告一段落之後,可以用下列命令對兩個文件同時進行操作。比如同時退出:

:qa (quit all)

如果希望保存全部文件:

:wa (write all)

或者是兩者的合並命令,保存全部文件,然後退出:

:wqa (write, then quit all)

如果在退出的時候不希望保存任何操作的結果:

:qa! (force to quit all)

上下文的展開和查看

比較和合並文件的時候經常需要結合上下文來確定最終要采取的操作。Vimdiff 缺省是會把不同之處上下各 6 行的文本都顯示出來以供參考。其他的相同的文本行被自動折疊。如果希望修改缺省的上下文行數,可以這樣設置:

:set diffopt=context:3

可以用簡單的折疊命令來臨時展開被折疊的相同的文本行:

zo (folding open,之所以用z這個字母,是因為它看上去比較像折疊著的紙)

然後可以用下列命令來重新折疊:

zc (folding close)

下圖是設置上下文為 3 行,並展開了部分相同文本的 vimdiff 屏幕:

技術分享圖片

結論

在無法使用圖形化的比較工具的時候,或者在需要快速比較和合並少量文件的時候,vimdiff 是最好的選擇。

今天就寫到這裏,有什麽疑問或出現什麽錯誤,隨時歡迎大神們發表評論指點迷津

Shell命令-文件及內容處理之diff、vimdiff