คำสั่ง diff เป็นวิธีง่ายๆ ในการเปรียบเทียบไฟล์หรือไดเรกทอรีจาก Shell ของ Linux บทความนี้จะแสดงวิธีการใช้งานพร้อมตัวอย่างการใช้งานทั่วไป
คำสั่ง diff ทำการเปรียบเทียบไฟล์หรือไดเรกทอรีสองรายการแบบบรรทัดต่อบรรทัด และแสดงผลความแตกต่างระหว่างพวกมัน
ทำไมคุณถึงต้องการเปรียบเทียบไฟล์หรือไดเรกทอรี?
- คุณอาจมีไฟล์สองไฟล์ที่ชื่อเหมือนกันและดูคล้ายกัน ต้องการดูความแตกต่างระหว่างพวกมัน
- เปรียบเทียบการเปลี่ยนแปลงของโค้ดโปรแกรมในโปรเจกต์ที่คุณกำลังสร้างระหว่างเวอร์ชันใหม่และเก่า
- คุณคัดลอกไฟล์จำนวนมากไปยังดิสก์อีกตัวหนึ่ง และต้องการตรวจสอบว่าทุกอย่างถูกคัดลอกสำเร็จโดยไม่มีการเสียหาย
- คุณและเพื่อนมีชุดไฟล์เดียวกันในโฟลเดอร์ คุณทำการเปลี่ยนแปลง แต่ไม่ต้องการส่งไฟล์ทั้งหมดให้เพื่อนอีกครั้ง คุณสามารถใช้ diff สร้างแพตช์ที่มีเฉพาะการเปลี่ยนแปลง ส่งให้พวกเขา แล้วพวกเขาสามารถอัปเดตไฟล์ของพวกเขาได้โดยไม่ต้องดาวน์โหลดทั้งหมดอีกครั้ง
คุณน่าจะมีเหตุผลของตัวเองในการเปรียบเทียบไฟล์ มาดู diff และวิธีใช้งานกัน
ไวยากรณ์ diff
diff OPTIONS FILES
โปรดทราบว่า:
- OPTIONS เป็น ตัวเลือก สามารถระบุได้จากตารางด้านล่าง
- FILES คือเส้นทางไปยังไฟล์สองไฟล์ที่ต้องการเปรียบเทียบ คั่นด้วยช่องว่าง
ตัวเลือก (Options) ของ diff
นี่คือตัวเลือก OPTIONS ที่ใช้บ่อยที่สุดสำหรับคำสั่ง diff ตามคู่มือผู้ใช้:
| ตัวเลือก | คำอธิบาย |
|---|---|
| -q, --brief | รายงานเฉพาะเมื่อไฟล์ต่างกัน |
| -s, --report-identical-files | รายงานเมื่อไฟล์สองไฟล์เหมือนกัน |
| -u, -U NUM, --unified[=NUM] | แสดงผล NUM บรรทัด (ค่าเริ่มต้น 3) ของบริบทแบบ unified |
| -N, --new-file | จัดการไฟล์ที่หายไปว่าเป็นไฟล์ว่าง |
| -l, --paginate | ส่งผ่าน 'pr' เพื่อแบ่งหน้า |
| -r, --recursive | เปรียบเทียบซับไดเรกทอรีแบบเรียกซ้ำ |
| --no-dereference | ไม่ติดตาม symbolic links |
| -a, --text | จัดการทุกไฟล์ว่าเป็นไฟล์ข้อความ |
| -d, --minimal | พยายามหาชุดการเปลี่ยนแปลงที่น้อยที่สุด |
| --speed-large-files | สมมติว่าเป็นไฟล์ขนาดใหญ่และมีการเปลี่ยนแปลงเล็กๆ จำนวนมากกระจายอยู่ |
คุณสามารถดูคู่มือเต็มได้ที่นี่ หรือรัน:
man diff
…จากบรรทัดคำสั่งเพื่อดูตัวเลือกทั้งหมด
ตัวอย่าง
การเปรียบเทียบไฟล์ด้วย diff ใน Linux
นี่คือการใช้งาน diff แบบง่ายที่สุด ซึ่งจะแสดงความแตกต่างระหว่างสองไฟล์ที่ระบุลงบนคอนโซล:
diff file1.txt file2.txt
การส่งทิศทางผลลัพธ์ (Redirecting Output)
หากคุณเพียงต้องการดูความแตกต่าง ไม่ใช่สร้างแพตช์ การส่งทิศทางผลลัพธ์ไปยังไฟล์มีประโยชน์ – เพื่อไม่ให้เทอร์มินัลตัดผลลัพธ์หากมีการเปลี่ยนแปลงมาก:
diff -q file1.txt file2.txt > differences.txt
สิ่งนี้จะสร้าง (หรือ เขียนทับ!) differences.txt ซึ่งจะสรุปความแตกต่างระหว่างสองไฟล์
ตัวเลือก -q ถูกเพิ่มเข้ามา เพื่อให้แสดงเฉพาะความแตกต่าง ไฟล์ที่เหมือนกันจะไม่ถูกกล่าวถึง ทำให้เห็นสถานการณ์ง่ายขึ้น
การเปรียบเทียบไดเรกทอรีด้วย diff
ไดเรกทอรีก็สามารถเปรียบเทียบได้โดยใช้ตัวเลือก -r (recursive) เพื่อเปรียบเทียบเนื้อหา:
diff -r -q /path/to/dir1 /path/to/dir2
อีกครั้ง ใช้ตัวเลือก -q ที่นี่เพื่อให้แสดงเฉพาะความแตกต่าง
การเปรียบเทียบไฟล์ขนาดใหญ่หรือไดเรกทอรีที่มีไฟล์ขนาดใหญ่
diff เป็นกระบวนการที่ใช้ทรัพยากรมาก – ทุกไฟล์ที่เปรียบเทียบต้องถูกอ่านและเปรียบเทียบ อาจใช้เวลานาน
ตัวเลือก --speed-large-files ปรับอัลกอริทึมของ diff ให้มีประสิทธิภาพมากขึ้นหากคุณกำลังเปรียบเทียบไฟล์ขนาดใหญ่ – ทำให้เร็วขึ้นเล็กน้อย
การสร้างแพตช์สำหรับไฟล์
เพื่อสร้าง แพตช์ – รายการความแตกต่างระหว่างสองไฟล์ที่สามารถนำไปประยุกต์กับอีกสำเนาของไฟล์แรกเพื่อให้เหมือนไฟล์ที่สอง สามารถใช้คำสั่งต่อไปนี้:
diff -u file1.txt file2.txt > update.patch
ตัวเลือก -u แสดงผลความแตกต่างในรูปแบบ unified ซึ่งสามารถนำไปใช้กับคำสั่ง patch เพื่ออัปเดตไฟล์ต้นฉบับด้วยการเปลี่ยนแปลงเหล่านั้น
สิ่งนี้มีประโยชน์หากคุณมีเพื่อนหรือเพื่อนร่วมงานที่ใช้ข้อมูลหรือโค้ดของคุณ และคุณต้องการส่งการอัปเดตที่คุณทำไปโดยไม่ต้องส่งชุดข้อมูลหรือแอปพลิเคชันทั้งหมดอีกครั้ง
การติดตั้งแพตช์สำหรับไฟล์
เมื่อเพื่อนของคุณได้รับแพตช์ พวกเขาสามารถนำไปใช้ด้วยคำสั่ง patch ต่อไปนี้:
patch original.txt < update.patch
การยกเลิกแพตช์สำหรับไฟล์
หากคุณทำผิดพลาด คุณสามารถยกเลิกแพตช์ได้โดยรันในโหมดย้อนกลับด้วยตัวเลือก -R:
patch -R original.txt < update.patch
การสร้างแพตช์สำหรับไดเรกทอรี
คำสั่งต่อไปนี้จะสร้างแพตช์สำหรับไดเรกทอรีทั้งหมด โดยรันตัวเลือก -r (recursive), -u (unified format), และ -N (treat absent files as empty):
diff -ruN originalDir updatedDir > update.patch
การติดตั้งแพตช์สำหรับไดเรกทอรี
แพตช์สามารถนำไปประยุกต์กับไดเรกทอรีโดยใช้ตัวเลือก -p0 ซึ่งจะนำแพตช์ไปประยุกต์กับโครงสร้างไดเรกทอรีเดียวกับที่สร้างขึ้น:
patch -p0 < update.patch
การยกเลิกแพตช์สำหรับไดเรกทอรี
สุดท้าย การยกเลิก/ย้อนกลับการแพตช์ของไดเรกทอรี:
patch -R -p0 originalFile < patchFile