คำสั่ง diff: การเปรียบเทียบไฟล์ รูปแบบแพตช์ของ diff -u และออปชัน

สภาพแวดล้อมทดสอบตระกูล RHELAlmaLinux 9.8บัญชี root

คำสั่ง diff เป็นคำสั่ง Linux ที่เปรียบเทียบไฟล์สองไฟล์ทีละบรรทัดและแสดงเฉพาะบรรทัดที่ต่างกัน เมื่อเปรียบเทียบไฟล์เก่ากับไฟล์ใหม่ที่จำลองการตั้งค่าเว็บเซิร์ฟเวอร์ด้วย diff ก็เห็นจุดที่เปลี่ยนสามจุดเป็นสามบรรทัด คือ 2,3c2,3, 5d4 และ 6a6 ส่วนไฟล์แพตช์ที่บันทึกด้วยออปชัน -u แสดงการเปลี่ยนแปลงเดียวกันด้วยเครื่องหมายลบและบวก

ชื่อไฟล์และเนื้อหาในผลลัพธ์ด้านล่าง รวมถึงโฟลเดอร์ทำงาน /root/work เป็นค่าตัวอย่าง ไฟล์ที่นำมาเปรียบเทียบทั้งหมดเป็นไฟล์ขนาดเล็กที่สร้างขึ้นเพื่อทดสอบ

1️⃣ วิธีใช้พื้นฐานของคำสั่ง diff และการอ่านผลลัพธ์

รูปพื้นฐานของคำสั่งคือ diff ออปชัน ไฟล์แรก และไฟล์ที่สอง ตามลำดับ คำสั่งจะแสดงพร้อมหมายเลขบรรทัดว่าต้องเปลี่ยน ลบ หรือเพิ่มบรรทัดใดเพื่อให้ไฟล์แรกเหมือนกับไฟล์ที่สอง

ไฟล์สองไฟล์ที่ใช้เปรียบเทียบเป็นไฟล์หกบรรทัดที่จำลองการตั้งค่าเว็บเซิร์ฟเวอร์

cd /root/work
cat config-old.conf
# app config
listen 80
server_name example.com
root /var/www/html
gzip off
log_level warn
cat 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.conf
2,3c2,3
< listen 80
< server_name example.com
---
> listen 443
> server_name example.com www.example.com
5d4
< gzip off
6a6
> cache on
echo $?
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.conf
echo $?
0

ถ้าระบุไฟล์ที่ไม่มีอยู่ จะขึ้นข้อความแสดงข้อผิดพลาดและรหัสออกคือ 2

diff config-old.conf nosuch.conf
diff: nosuch.conf: No such file or directory
echo $?
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 @@ คือก้อน (hunk) ที่รวม 6 บรรทัดนับจากบรรทัดที่ 1 ของไฟล์แรกกับ 6 บรรทัดนับจากบรรทัดที่ 1 ของไฟล์ที่สอง บรรทัดถัดลงมา ถ้าขึ้นต้นด้วย - คือบรรทัดที่ลบออกจากไฟล์แรก ขึ้นต้นด้วย + คือบรรทัดที่เพิ่มในไฟล์ที่สอง และขึ้นต้นด้วยช่องว่างคือบรรทัดที่เหมือนกันในทั้งสองไฟล์

-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.patch
echo $?
1
cat /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.txt
Listen 80
ServerName example.com
DocumentRoot /var/www/html
cat case-b.txt
listen 80
ServerName  example.com

DocumentRoot /var/www/html
diff case-a.txt case-b.txt
1,2c1,3
< Listen 80
< ServerName example.com
---
> listen 80
> ServerName  example.com
>

เมื่อเปรียบเทียบโดยไม่ใส่ออปชัน บรรทัดที่ 1–2 ซึ่งมีความหมายเหมือนกันก็แสดงเป็นบรรทัดที่เปลี่ยนด้วย เมื่อไม่สนใจตัวพิมพ์เล็กใหญ่ด้วย -i บรรทัด Listen จะหายไปและเหลือเฉพาะบรรทัดที่ 2 ของไฟล์แรก

diff -i case-a.txt case-b.txt
2c2,3
< ServerName example.com
---
> ServerName  example.com
>

เมื่อเพิ่ม -w จะไม่สนใจช่องว่างทั้งหมดในบรรทัด บรรทัด ServerName จึงกลายเป็นบรรทัดที่เหมือนกัน และเหลือเพียงบรรทัดว่างหนึ่งบรรทัดที่เพิ่มในบรรทัดที่ 3 เมื่อใส่ -b ซึ่งไม่สนใจเฉพาะจำนวนช่องว่างแทน -w ก็ได้ผลเหมือนกันกับไฟล์นี้

diff -i -w case-a.txt case-b.txt
2a3
>

เมื่อใส่ -B ด้วย ความต่างของบรรทัดว่างก็ไม่ถูกนับ คำสั่งจึงจบด้วยรหัสออก 0 โดยไม่มีผลลัพธ์

diff -i -w -B case-a.txt case-b.txt
echo $?
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.conf
listen 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.conf
Files config-old.conf and config-new.conf differ
diff -s config-old.conf config-copy.conf
Files 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ไม่สนใจความต่างนั้นถ้าบรรทัดที่เปลี่ยนทั้งหมดตรงกับ regex
-Z, --ignore-trailing-spaceไม่สนใจช่องว่างท้ายบรรทัด
-E, --ignore-tab-expansionไม่สนใจความต่างที่เกิดจากการเปลี่ยนแท็บเป็นช่องว่าง
-a, --textถือว่าไฟล์ทั้งหมดเป็นข้อความ
--strip-trailing-crตัดอักขระ carriage return ท้ายบรรทัดออกก่อนเปรียบเทียบ
--colorWHENใส่สีในผลลัพธ์ WHEN คือ never, always, auto
-v, --versionแสดงข้อมูลเวอร์ชัน

🔲 ซิมูเลเตอร์คำสั่ง diff

ในซิมูเลเตอร์ด้านล่าง พิมพ์ diff เองได้ด้วยไฟล์ตัวอย่างในบทความ บันทึกไฟล์แพตช์ด้วย -u หรือเปรียบเทียบด้วย -i -w -B และ -rq ได้ และเมื่อเพิ่มบรรทัดหนึ่งบรรทัดใน config-new.conf แล้วเปรียบเทียบอีกครั้ง ก็จะได้ผลลัพธ์ที่เปลี่ยนไป

ซิมูเลเตอร์คำสั่ง diffdiff · บัญชี root
[root@server work]#
ใช้ปุ่ม ↑↓ บนแป้นพิมพ์เพื่อเรียกคำสั่งที่พิมพ์ไว้ก่อนหน้ากลับมา

4️⃣ เปรียบเทียบโฟลเดอร์ด้วย diff -r

เมื่อต้องการเปรียบเทียบหลายไฟล์พร้อมกัน เช่น ก่อนและหลังดีพลอยไฟล์ของเว็บไซต์ ให้ระบุชื่อโฟลเดอร์แทนไฟล์ โฟลเดอร์ตัวอย่าง site-v1 และ site-v2 มี index.html และโฟลเดอร์ css เหมือนกัน ส่วน about.html และ contact.html มีอยู่เพียงฝั่งเดียว

diff site-v1 site-v2
Only 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 จะแสดงไปถึงค่าสีที่เปลี่ยนใน style.css ในโฟลเดอร์ css

diff -r site-v1 site-v2
Only 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-v2
Only 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 & เนื้อหาแนะนำ

cmp เปรียบเทียบไฟล์สองไฟล์ทีละไบต์และแสดงเฉพาะตำแหน่งแรกที่ต่างกันเพียงจุดเดียว ผลจากการเปรียบเทียบไฟล์ตั้งค่าสองไฟล์ในบทความด้วย cmp คือบรรทัดเดียว [config-old.conf config-new.conf differ: char 21, line 2] ใช้เมื่อต้องการตรวจว่าไฟล์บีบอัดหรือรูปภาพ ซึ่งการเปรียบเทียบทีละบรรทัดไม่มีความหมาย เหมือนกันหรือไม่

ส่งไฟล์ต้นฉบับและไฟล์แพตช์ให้คำสั่ง patch ตามลำดับ ([patch config-old.conf config.patch]) patch จะแก้ไฟล์ต้นฉบับตรงนั้นเลย จึงควรเขียนผลลัพธ์ลงไฟล์อื่นด้วย -o หรือใช้กับสำเนาก่อน

ใส่สีได้ด้วยออปชัน --color[=WHEN] โดยตำแหน่ง WHEN ใส่ never, always หรือ auto ส่วน --color ที่ไม่ระบุค่าจะเหมือนกับ auto คือใส่สีเฉพาะเมื่อแสดงผลบนเทอร์มินัล ถ้าต้องการให้สียังอยู่เมื่อส่งต่อให้คำสั่งอื่นอย่าง less ให้ใช้ --color=always

🔗 เนื้อหาแนะนำ
ซิงก์ไฟล์ · rsync คำสั่ง Rsync ของ Linux: ออปชันและตัวอย่างการใช้ บทความที่รวบรวมออปชันของ rsync ซึ่งเปรียบเทียบต้นทางกับปลายทางแล้วส่งเฉพาะไฟล์ที่เปลี่ยน พร้อมตัวอย่างการใช้ระหว่างโฟลเดอร์ในเครื่องกับเซิร์ฟเวอร์ SSH อ่านบทความ → คำสั่ง rsync_ส่งจากโลคัลไปยังระยะไกล
🪐อ้างอิงแหล่งทางการ 3

ℹ️ ประกาศเรื่องลิงก์แอฟฟิลิเอต
เนื้อหาของเว็บไซต์นี้มีลิงก์แอฟฟิลิเอต หากผู้เข้าชมซื้อสินค้าหรือบริการผ่านลิงก์เหล่านี้ เว็บไซต์นี้จะได้รับค่าคอมมิชชันจากผู้ขาย ในกระบวนการนี้ ราคาที่ผู้ซื้อจ่าย(ราคาจะลดลงเมื่อมีโปรโมชัน↓)จะไม่สูงขึ้นแต่อย่างใด ราคา ส่วนลด และข้อมูลสต็อกที่แสดงเป็นข้อมูล ณ เวลาที่เขียนและอาจต่างจากความเป็นจริง โปรดตรวจสอบกับผู้ขายอีกครั้งก่อนซื้อ การเลือกและการประเมินสินค้าเขียนตามเกณฑ์ของเราเอง และการได้รับค่าคอมมิชชันหรือไม่ไม่มีผลต่อลำดับการแนะนำหรือเนื้อหาการประเมิน

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *

Prove your humanity: 2   +   6   =