คำสั่ง 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 @@ คือก้อน (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.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 เมื่อใส่ -b ซึ่งไม่สนใจเฉพาะจำนวนช่องว่างแทน -w ก็ได้ผลเหมือนกันกับไฟล์นี้
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 | ไม่สนใจความต่างนั้นถ้าบรรทัดที่เปลี่ยนทั้งหมดตรงกับ 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 แล้วเปรียบเทียบอีกครั้ง ก็จะได้ผลลัพธ์ที่เปลี่ยนไป
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 จะแสดงไปถึงค่าสีที่เปลี่ยนใน style.css ในโฟลเดอร์ 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 & เนื้อหาแนะนำ
Linux · ข้อความ
คำสั่ง grep ของ Linux
วิธีใช้ grep เพื่อค้นหาและแสดงเฉพาะบรรทัดที่มีสตริงที่ต้องการจากไฟล์ข้อความ เช่น ไฟล์ล็อก
Linux · ข้อความ
คำสั่ง sort ของ Linux: การเรียงไฟล์
ตัวเลือกและตัวอย่างการใช้ sort เพื่อเรียงเนื้อหาไฟล์ตามตัวอักษร จากน้อยไปมาก หรือจากมากไปน้อย
Linux · ข้อความ
คำสั่ง uniq ของ Linux
วิธีใช้ uniq เพื่อเหลือบรรทัดที่ซ้ำไว้เพียงบรรทัดเดียว และนับจำนวนครั้งที่ซ้ำด้วย -c
ℹ️ ประกาศเรื่องลิงก์แอฟฟิลิเอต
เนื้อหาของเว็บไซต์นี้มีลิงก์แอฟฟิลิเอต หากผู้เข้าชมซื้อสินค้าหรือบริการผ่านลิงก์เหล่านี้ เว็บไซต์นี้จะได้รับค่าคอมมิชชันจากผู้ขาย ในกระบวนการนี้ ราคาที่ผู้ซื้อจ่าย(ราคาจะลดลงเมื่อมีโปรโมชัน↓)จะไม่สูงขึ้นแต่อย่างใด ราคา ส่วนลด และข้อมูลสต็อกที่แสดงเป็นข้อมูล ณ เวลาที่เขียนและอาจต่างจากความเป็นจริง โปรดตรวจสอบกับผู้ขายอีกครั้งก่อนซื้อ การเลือกและการประเมินสินค้าเขียนตามเกณฑ์ของเราเอง และการได้รับค่าคอมมิชชันหรือไม่ไม่มีผลต่อลำดับการแนะนำหรือเนื้อหาการประเมิน