diff 指令:檔案比較、diff -u 修補檔格式與選項整理
diff 指令是逐行比較兩個檔案、只輸出不同行的 Linux 指令。用 diff 比較模擬網頁伺服器設定的舊檔案與新檔案後,三處變更以 2,3c2,3、5d4、6a6 三行呈現,而用 -u 選項儲存的修補檔則以減號與加號整理出相同的變更。
以下輸出中的檔案名稱與內容,以及工作資料夾 /root/work 都是範例值。比較用的檔案全都是為了測試而建立的小檔案。
1️⃣ diff 指令的基本用法與輸出讀法
指令的基本形式依序是 diff、選項、第一個檔案、第二個檔案。它會連同行號輸出,要讓第一個檔案與第二個檔案相同,必須修改、刪除、新增哪些行。
用來比較的兩個檔案,是模擬網頁伺服器設定的六行檔案。
cd /root/workcat config-old.conf# app config
listen 80
server_name example.com
root /var/www/html
gzip off
log_level warncat config-new.conf# app config
listen 443
server_name example.com www.example.com
root /var/www/html
log_level warn
cache on不加選項比較了這兩個檔案。
diff config-old.conf config-new.conf2,3c2,3
< listen 80
< server_name example.com
---
> listen 443
> server_name example.com www.example.com
5d4
< gzip off
6a6
> cache onecho $?1輸出中位置行與內容行交替出現。位置行中間的字母 c 是修改、d 是刪除、a 是新增,字母左邊是第一個檔案的行號,右邊是第二個檔案的行號。有不同之處時,結束代碼是 1。
| 輸出 | 說明 |
|---|---|
| 2,3c2,3 | 把第一個檔案的第 2~3 行改成第二個檔案的第 2~3 行(change) |
| 5d4 | 刪除第一個檔案的第 5 行(delete)。刪除後會對上第二個檔案第 4 行之後 |
| 6a6 | 在第一個檔案的第 6 行之後加上第二個檔案的第 6 行(add) |
| < 行 | 第一個檔案中的行 |
| > 行 | 第二個檔案中的行 |
| --- | 修改的行(c)中,第一個檔案一側與第二個檔案一側的分界 |
比較內容相同的檔案時,不會輸出任何內容,並以結束代碼 0 結束。
diff config-old.conf config-copy.confecho $?0指定不存在的檔案時,會出現錯誤訊息,結束代碼是 2。
diff config-old.conf nosuch.confdiff: nosuch.conf: No such file or directoryecho $?2在指令稿中,可以用這三個值區分相同、不同與錯誤。
2️⃣ diff -u 統一格式與修補檔
預設輸出只有變更的行,因此在有數百行的設定檔中,很難看出那些行在哪個設定附近。加上 -u 後,會以統一格式(unified)輸出,把變更行前後各最多三行一併納入。
diff -u config-old.conf config-new.conf--- config-old.conf 2026-10-29 02:24:50.840228932 +0000
+++ config-new.conf 2026-10-29 02:24:50.840228932 +0000
@@ -1,6 +1,6 @@
# app config
-listen 80
-server_name example.com
+listen 443
+server_name example.com www.example.com
root /var/www/html
-gzip off
log_level warn
+cache on開頭兩行(---、+++)顯示兩個檔案的名稱與修改時間,@@ -1,6 +1,6 @@ 這一行則是把第一個檔案從第 1 行起的 6 行與第二個檔案從第 1 行起的 6 行合在一起的區塊(hunk)。其下的各行,開頭是 - 表示從第一個檔案刪除的行,開頭是 + 表示加到第二個檔案的行,開頭是空白則表示兩個檔案中相同的行。
-c 是上下文格式(context)。它會分別輸出第一個檔案的區塊與第二個檔案的區塊,變更的行前面有驚嘆號,刪除的行有減號,新增的行有加號。
diff -c config-old.conf config-new.conf*** config-old.conf Thu Oct 29 02:24:50 2026
--- config-new.conf Thu Oct 29 02:24:50 2026
***************
*** 1,6 ****
# app config
! listen 80
! server_name example.com
root /var/www/html
- gzip off
log_level warn
--- 1,6 ----
# app config
! listen 443
! server_name example.com www.example.com
root /var/www/html
log_level warn
+ cache on同樣的變更,-c 因為未變更的行在兩個區塊各出現一次,所以比 -u 長。
把 -u 的輸出存成檔案,那個檔案就是修補檔。即使把輸出送到檔案,diff 的結束代碼仍然是 1。
diff -u config-old.conf config-new.conf > /root/work/config.patchecho $?1cat /root/work/config.patch--- config-old.conf 2026-10-29 02:24:50.840228932 +0000
+++ config-new.conf 2026-10-29 02:24:50.840228932 +0000
@@ -1,6 +1,6 @@
# app config
-listen 80
-server_name example.com
+listen 443
+server_name example.com www.example.com
root /var/www/html
-gzip off
log_level warn
+cache on儲存的檔案內容與畫面上輸出的 -u 結果相同。把這個檔案交給 patch 指令,就能把第一個檔案改成與第二個檔案相同的內容。
3️⃣ diff 選項整理與忽略空白、大小寫
用手抄寫設定時,會出現內容相同、只有大小寫或空白不同的行。第二組範例檔案把第一行的大寫 L 改成小寫,把第二行的一個空白改成兩個,並加了一個空行。
cat case-a.txtListen 80
ServerName example.com
DocumentRoot /var/www/htmlcat case-b.txtlisten 80
ServerName example.com
DocumentRoot /var/www/htmldiff case-a.txt case-b.txt1,2c1,3
< Listen 80
< ServerName example.com
---
> listen 80
> ServerName example.com
>不加選項比較時,意思相同的第 1~2 行也會顯示為變更的行。用 -i 忽略大小寫後,Listen 這一行消失,只剩第一個檔案的第 2 行。
diff -i case-a.txt case-b.txt2c2,3
< ServerName example.com
---
> ServerName example.com
>再加上 -w 會忽略行內所有空白,ServerName 這一行也變成相同的行,只剩在第 3 行加上的一個空行。把 -w 換成只忽略空白數量的 -b,在這組檔案中也得到相同的結果。
diff -i -w case-a.txt case-b.txt2a3
>連 -B 也加上後,空行的差異也會被忽略,因此沒有輸出,並以結束代碼 0 結束。
diff -i -w -B case-a.txt case-b.txtecho $?0要把兩個檔案左右並排檢視時,使用 -y。預設寬度是 130 欄,因此用 -W 70 縮小。
diff -y -W 70 config-old.conf config-new.conf# app config # app config
listen 80 | listen 443
server_name example.com | server_name example.com www.ex
root /var/www/html root /var/www/html
gzip off <
log_level warn log_level warn
> cache on中間的直線(|)表示變更的行,< 表示只在第一個檔案中的行,> 表示只在第二個檔案中的行。寬度縮小後,較長的行會被截斷。server_name 這一行在右側只顯示到 www.ex。
加上 --suppress-common-lines 後,會去掉相同的行,只留下不同的行。
diff -y --suppress-common-lines -W 70 config-old.conf config-new.conflisten 80 | listen 443
server_name example.com | server_name example.com www.ex
gzip off <
> cache on只想確認相同或不同、而不看差異內容時,使用 -q。檔案相同時 -q 不會輸出任何內容,因此要得到一行說明兩者相同的訊息,就使用 -s。
diff -q config-old.conf config-new.confFiles config-old.conf and config-new.conf differdiff -s config-old.conf config-copy.confFiles config-old.conf and config-copy.conf are identical選項整理在下方兩個分頁。
| 選項 | 複製 | 說明 |
|---|---|---|
| -u, --unified | 以統一格式輸出,把變更行前後各最多三行一併納入 | |
| -c, --context | 分別輸出第一個檔案區塊與第二個檔案區塊的上下文格式 | |
| -i, --ignore-case | 忽略大小寫的差異 | |
| -w, --ignore-all-space | 忽略行內所有空白 | |
| -b, --ignore-space-change | 只忽略空白數量的差異 | |
| -B, --ignore-blank-lines | 忽略空行的差異 | |
| -y, --side-by-side | 把兩個檔案左右並排輸出 | |
| -W, --widthNUM | 指定並排輸出時的寬度。預設值是 130 欄 | |
| --suppress-common-lines | 並排輸出時去掉相同的行,只輸出不同的行 | |
| -q, --brief | 只輸出相同或不同。相同時不輸出任何內容 | |
| -s, --report-identical-files | 兩個檔案相同時,輸出一行說明兩者相同的訊息 | |
| -r, --recursive | 連子資料夾內的檔案也一併比較 |
| 選項 | 複製 | 說明 |
|---|---|---|
| -U, --unifiedNUM | 指定統一格式中一併輸出的前後行數。預設值是 3 | |
| -N, --new-file | 把其中一側沒有的檔案視為空檔案 | |
| -x, --excludePAT | 把名稱符合樣式的檔案排除在比較之外 | |
| -I, --ignore-matching-linesRE | 變更的行全都符合正規表示式時,忽略該差異 | |
| -Z, --ignore-trailing-space | 忽略行尾的空白 | |
| -E, --ignore-tab-expansion | 忽略把定位字元換成空白所產生的差異 | |
| -a, --text | 把所有檔案視為文字 | |
| --strip-trailing-cr | 去掉行尾的歸位字元後再比較 | |
| --colorWHEN | 為輸出加上顏色。WHEN 是 never、always、auto | |
| -v, --version | 輸出版本資訊 |
🔲 diff 指令模擬器
在下方的模擬器中,可以用本文的範例檔案直接輸入 diff。可以用 -u 儲存修補檔,或用 -i -w -B、-rq 比較,在 config-new.conf 加一行後再比較一次,就會出現變更後的結果。
4️⃣ 用 diff -r 比較資料夾
像部署網站檔案的前後那樣要一次比較多個檔案時,就寫資料夾名稱而不是檔案。範例資料夾 site-v1 與 site-v2 都有 index.html 與 css 資料夾,about.html 與 contact.html 則各只在其中一側。
diff site-v1 site-v2Only in site-v1: about.html
Only in site-v2: contact.html
Common subdirectories: site-v1/css and site-v2/css
diff site-v1/index.html site-v2/index.html
2,3c2,3
< <p>Version 1</p>
< <a href="about.html">About</a>
---
> <p>Version 2</p>
> <a href="contact.html">Contact</a>不加選項比較資料夾時,只在其中一側的檔案以 [Only in] 行顯示,子資料夾只以 [Common subdirectories] 行顯示,不會比較子資料夾內的檔案。兩個資料夾中同名的 index.html,會在 [diff site-v1/index.html site-v2/index.html] 行之下輸出差異。加上 -r 後,連 css 資料夾內 style.css 中變更的顏色值也會輸出。
diff -r site-v1 site-v2Only in site-v1: about.html
Only in site-v2: contact.html
diff -r site-v1/css/style.css site-v2/css/style.css
2c2
< h1 { color: #222; }
---
> h1 { color: #0a58ca; }
diff -r site-v1/index.html site-v2/index.html
2,3c2,3
< <p>Version 1</p>
< <a href="about.html">About</a>
---
> <p>Version 2</p>
> <a href="contact.html">Contact</a>檔案很多的資料夾,先用 -rq 確認變更的檔案清單,再用 diff 只比較需要的檔案。
diff -rq site-v1 site-v2Only in site-v1: about.html
Only in site-v2: contact.html
Files site-v1/css/style.css and site-v2/css/style.css differ
Files site-v1/index.html and site-v2/index.html differ🔢 FAQ & 推薦內容
ℹ️ 聯盟行銷說明
本站內容包含聯盟行銷連結。訪客透過這些連結購買商品或服務時,本站會從賣家獲得佣金。在這個過程中,購買者支付的金額(遇到活動折扣時金額會降低↓)並不會因此提高。刊登的價格、折扣與庫存資訊以撰寫當時為準,可能與實際情況不同,購買前請向賣家做最後確認。商品的挑選與評價依本站自訂的標準撰寫,是否支付佣金不會影響介紹順序或評價內容。