เมื่อกำหนดไดเรกทอรีต้นไม้สองต้นฉันจะค้นหาไฟล์ที่แตกต่างกันตามเนื้อหาได้อย่างไร


786

ถ้าฉันต้องการหาความแตกต่างระหว่างทรีไดเร็กตอรี่สองต้นฉันมักจะรัน:

diff -r dir1/ dir2/

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

ข้อเสนอแนะใด ๆ



1
ด้วยความเคารพต่อหนึ่งในไดเรกทอรีวิธีการรับเฉพาะไฟล์ / ไดเรกทอรีซึ่งเป็นพิเศษในอื่น ๆ ?
Sandeepan Nath

ใช้dircmpคำสั่งบนยูนิกซ์ (ไม่ใช่ linux)
roblogic

คำตอบ:


1118

คุณพูดว่า Linux ดังนั้นคุณโชคดี (อย่างน้อยควรมีให้ใช้ แต่ไม่แน่ใจว่าเมื่อใดที่มันถูกเพิ่ม):

diff --brief --recursive dir1/ dir2/ # GNU long options
diff -qr dir1/ dir2/ # common short options

ควรทำในสิ่งที่คุณต้องการ

หากคุณต้องการเห็นความแตกต่างของไฟล์ที่อาจไม่มีอยู่ในไดเรกทอรีใด:

diff --brief --recursive --new-file dir1/ dir2/ # GNU long options
diff -qrN dir1/ dir2/ # common short options

12
ดี แต่สั้นกว่าคือdiff -qr dir1/ dir2/และรุ่นเสริมของฉันไปdiff -qr dir1/ dir2/ | grep ' differ'
sobi3ch

1
@skv ทำไม มันเป็นคำสั่งเดียวกับคำตอบ ฉันเปลี่ยน--briefเป็นทางลัด-qเท่านั้น
sobi3ch

2
@skv ไม่ใช่สิ่งที่คำถามเดิมถาม แต่การปรับปรุงคำตอบเพื่อรองรับคำถามนี้เช่นกัน
Mark Loeser

3
@MikeMaxwell --briefจะต้องมี -briefถูกตีความว่า-b -r -i -e -fในคำอื่น ๆ เช่นชุดของธงไม่ได้เป็นตัวเลือกเดียว
daboross

2
@daboross: ว้าวฉันใช้ Unix / Linux มาตลอดและฉันก็ไม่เคยรู้เลยว่ามีความแตกต่างระหว่าง '-' และ '-' (ฉันไม่คิดว่า '-' มีอยู่เมื่อฉันเริ่มต้น) ขอขอบคุณสำหรับคำอธิบาย!
Mike Maxwell

287

คำสั่งที่ฉันใช้คือ:

diff -qr dir1/ dir2/

มันเป็นเหมือนกับมาร์ค :) แต่คำตอบของเขาใส่ใจฉันที่จะใช้ที่แตกต่างกันประเภทของธงและมันทำให้ฉันดูสองครั้ง การใช้ธง verbose ที่มากขึ้นของ Mark จะเป็น:

diff  --brief --recursive dir1/ dir2/

ฉันขอโทษที่โพสต์เมื่อคำตอบอื่น ๆ เป็นที่ยอมรับอย่างสมบูรณ์ หยุดตัวเองไม่ได้ ... กำลังทำเรื่องอวดน้อยลง


3
ชื่นชมความมั่นคงอย่างสมบูรณ์ - แต่อย่ารู้สึกแย่ ฉัน upvoted คำตอบของมาร์คเกินไป;)
เจอราร์ด ONeill

10
.. ดังนั้นมันสมเหตุสมผลหรือไม่ที่ใส่คำตอบที่แตกต่างกับเพียงแค่รสชาติที่แตกต่างกัน? อย่าเลย! มันสมเหตุสมผลหรือไม่ที่จะรวมทั้งคำตอบเข้ากับคำตอบที่สอดคล้องกัน? ใช่! ;)
sobi3ch

1
แค่คำถาม; สิ่งที่qยืนสำหรับ มันเป็นตัวย่อของบางสิ่งบางอย่าง? ฉันไม่สามารถหาเหตุผลใด ๆ ที่อยู่เบื้องหลังq..
kramer65

3
@ kramer65 - มันเหมือนกับ "- สั้น ๆ " แต่ฉันคิดว่าคุณสงสัยว่าทำไม q? บางทีเพื่อความรวดเร็ว? "-b" ถูกใช้โดย "ละเว้นการเปลี่ยนแปลงในพื้นที่สีขาว" ตามหน้า man
FPC

4
@ kramer65 ฉันเชื่อว่าqมีไว้สำหรับquietโดยทั่วไปหมายถึง verbose น้อยกว่า
Gogeta70

105

ฉันชอบที่จะใช้git diff --no-index dir1/ dir2/เพราะมันสามารถแสดงความแตกต่างของสี (ถ้าคุณมีตัวเลือกที่กำหนดไว้ในการตั้งค่า git ของคุณ) และเพราะมันแสดงให้เห็นถึงความแตกต่างทั้งหมดในเอาต์พุตหน้าจั่วโดยใช้ "น้อย"


25
เรียบร้อย ใครจะเดาได้ว่าคอมไพล์สามารถทำไดเร็กตอรี่โดยพลการไม่ใช่แค่ repo เทียบกับไฟล์?
Dan Dascalescu

2
Perl สคริปต์colordiffมีประโยชน์มากที่นี่สามารถใช้กับ svn และ diff ทั่วไป
Felipe Alvarez

4
ถ้าคุณเปรียบเทียบ (เช่นฉัน) 2 dirs เป็นแยกคอมไพล์โครงการ / Repos แล้วคุณจะต้องเพิ่ม--no-indexมากขึ้นในการstackoverflow.com/a/1792477/473390 ฉันได้รับคำตอบ @ alan-porter
sobi3ch

ฉันชอบอันนี้ฉันยังพบว่าหากคุณเพิ่มลง--name-status ในบรรทัดคำสั่งมันจะแสดงรายการชื่อไฟล์ที่มีการตั้งค่าสถานะ "M / A / D" สำหรับสถานะ Modified / Added / Deleted
gzh

มันเกิดขึ้นเพื่อให้ทั้งสองไดเรกทอรีมีโฟลเดอร์. git จริงฉันจะแยกออกจากการเปรียบเทียบได้อย่างไร
Muhamed Cicak

35

สองคำสั่งเหล่านี้ทำสิ่งที่ขอ:

diff --brief --recursive --no-dereference --new-file --no-ignore-file-name-case /dir1 /dir2 > dirdiff_1.txt

rsync --recursive --delete --links --checksum --verbose --dry-run /dir1/ /dir2/ > dirdiff_2.txt

ตัวเลือกระหว่างพวกเขาขึ้นอยู่กับตำแหน่งของ dir1 และ dir2:

เมื่อไดเรกทอรีอยู่ในไดรฟ์แยกสองไดรฟ์ให้ทำงานต่างกันดีกว่า rsync แต่เมื่อเปรียบเทียบทั้งสองไดเร็กทอรีในไดรฟ์เดียวกัน rsync ก็จะเร็วขึ้น นั่นเป็นเพราะ diff ทำให้การโหลดเกือบเท่ากันในทั้งสองไดเรกทอรีขนานกันทำให้การโหลดสูงสุดในไดรฟ์ทั้งสอง

rsync คำนวณ checksums เป็นกลุ่มก้อนขนาดใหญ่ก่อนทำการเปรียบเทียบจริง ที่จัดกลุ่มการดำเนินงานของ i / o ในกลุ่มก้อนใหญ่และนำไปสู่การประมวลผลที่มีประสิทธิภาพมากขึ้นเมื่อสิ่งต่าง ๆ เกิดขึ้นในไดรฟ์เดียว


3
rsync ไม่ได้เป็นเพียงได้เร็วขึ้นสำหรับไฟล์บนไดรฟ์เดียว แต่ยัง allowes สำหรับการเปรียบเทียบไฟล์ใน subdirs เช่นrsync --options /usr /bin /var /sbin /lib /old_rootได้อย่างมีประสิทธิภาพจะเปรียบเทียบรากปัจจุบัน/(โดยระบุ subdirs ทั้งหมดในนั้น) และ/old_root(ที่มีตัวอย่างเช่นบางสำรองเก่า/) ซึ่งเป็นสิ่งที่diff -rสามารถ ไม่ต้องทำ และถ้าคุณสมมติไฟล์ที่มีขนาดเดียวกันสิทธิ์และ timestamps อาจจะยังไม่ได้เปลี่ยนออกจาก--checksumจะให้คุณได้อย่างรวดเร็ว (ถ้าไม่ผ่าน) ตรวจสอบว่าไฟล์อาจมีการเปลี่ยนแปลง
Matija Nalis

1
จุดประสงค์ของการ--deleteใช้rsyncคืออะไร?
Tom Hale

2
วัตถุประสงค์ของ --delete คือการลบไฟล์ที่มีอยู่ในปลายทาง -dir ซึ่งไม่มี (อีกต่อไป) อยู่ในแหล่งที่มา -dir
โทมัส Munk

2
ในกรณีนี้ (ด้วย--dry-runค่าสถานะ) ไม่มีอะไรถูกลบจริง ๆrsyncพิมพ์เฉพาะไฟล์ที่อยู่ใน dir1 แต่ไม่ได้อยู่ใน dir2
mata

11
ฉันแนะนำให้ใส่--dry-runก่อนเสมอเพื่อไม่ให้ลืมโดยไม่ตั้งใจ
Dave Rager

22

Meldยังเป็นเครื่องมือที่ยอดเยี่ยมสำหรับการเปรียบเทียบสองไดเรกทอรี:

meld dir1/ dir2/

Meld มีตัวเลือกมากมายสำหรับการเปรียบเทียบไฟล์หรือไดเรกทอรี หากสองไฟล์แตกต่างกันเป็นเรื่องง่ายที่จะเข้าสู่โหมดเปรียบเทียบไฟล์และดูความแตกต่างที่แน่นอน


2
ดี ฉันได้เขียนสคริปต์ Perl ง่าย ๆ เพื่อทำการเปรียบเทียบกับต้นไม้ แต่ฉันกำลังตีข้อ จำกัด นี่น่าจะเป็นตั๋ว
David Tonhofer

ปัญหาเดียวก็คือว่ามันไม่ได้ยืมตัวไปสคริปต์เนื่องจากมันเป็น app กราฟิก แต่มันจะดีถ้าคุณไม่สนใจ GUI! ขอบคุณ
DeanM

ฉันพบว่าmeldกลายเป็นซบเซาอย่างน่ากลัวหากใช้ในไดเรกทอรีขนาดใหญ่ว่า มีอะไรที่จัดการกับไดเรกทอรีขนาดใหญ่ได้ดีกว่าหรือไม่
ป๊อปอัพ

@Popup ไม่ใช่ที่ฉันรู้ คุณสามารถค้นหาชื่อไฟล์ที่แตกต่างกันได้ในบางสิ่งเช่นนี้ แต่:find dir1 dir2 | cut -d/ -f2- | sort | uniq --unique
Alexander

1
@Alexander - ในกรณีที่ฉันพบว่าmeld <(find dir1 -ls ) <(find dir2 -ls)ทำงานได้ค่อนข้างดีโดยใช้การทดแทนกระบวนการทุบตี ( =(command)ผลงานของ zsh ดียิ่งขึ้น)
ป๊อปอัป

10

Channel compatriot 'billings' (จาก freenode / # centos fame) ได้แชร์วิธีการของเขากับฉัน:

diff -Naur dir1/ dir2

การรวมสแลชไดเร็กทอรีสุดท้ายไปข้างหน้าไม่สำคัญ

นอกจากนี้ยังปรากฏ -uตัวเลือกใน diff / รุ่นเซิร์ฟเวอร์เก่าบางรุ่น

ความแตกต่างในความต่าง:

# diff -Nar /tmp/dir1 /tmp/dir2/
diff -Nar /tmp/dir1/file /tmp/dir2/file
28a29
> TEST

# diff -qr /tmp/dir1/ /tmp/dir2/
Files /tmp/dir1/file and /tmp/dir2/file differ

2
นั่นคือ--new-file/-Nสิ่งที่ทำให้ diff พิจารณาว่าไฟล์ที่ขาดหายไปนั้นว่างเปล่าและ--text/-aเป็นสาเหตุให้พิจารณาอินพุตไบนารี่ทั้งหมดเป็นข้อความ ฉันไม่เห็น Upsides สำหรับกรณีการใช้งานเฉพาะนี้
phk

4

Diffoscopeเป็นไดเรกทอรีบรรทัดคำสั่งที่ยอดเยี่ยม

ฉันชอบมันโดยเฉพาะอย่างยิ่งมันสามารถแตกต่างกันเป็นไฟล์:

มันจะแยกไฟล์ที่เก็บถาวรหลายชนิดซ้ำและแปลงรูปแบบไบนารีต่าง ๆ ให้เป็นรูปแบบที่มนุษย์อ่านได้มากขึ้นเพื่อเปรียบเทียบ มันสามารถเปรียบเทียบ tarballs สองรูป, ISO หรือ PDF ได้อย่างง่ายดาย

มันจะไม่เพียง แต่บอกคุณว่าไฟล์แตกต่างกัน แต่ยังแตกต่างกันอย่างไร


4

ในการค้นหา diff ใช้คำสั่งนี้:

diff -qr dir1/ dir2/

-rจะกระจายไดเรกทอรีย่อยทั้งหมดด้วย -qบอกให้ diff รายงานเฉพาะเมื่อไฟล์ต่างกัน

diff  --brief dir1/ dir2/

- บทสรุปจะแสดงไฟล์ที่มี dosent อยู่ในไดเรกทอรี

หรืออื่น ๆ

เราสามารถใช้ Meld ซึ่งจะแสดงในหน้าต่างกราฟิกมันง่ายต่อการค้นหาความแตกต่าง

meld  dir1/ dir2/

2
--briefและ-qเป็นตัวเลือกเดียวกัน คำสั่งของคุณทำให้ดูเหมือนว่าพวกเขาจะแตกต่างกัน แต่พวกเขาไม่ได้
Elijah Lynn

2

คุณสามารถยังใช้และRsync findสำหรับfind:

find $FOLDER -type f | cut -d/ -f2- | sort > /tmp/file_list_$FOLDER

แต่ไฟล์ที่มีชื่อเดียวกันและในโฟลเดอร์ย่อยเดียวกัน แต่มีเนื้อหาต่างกันจะไม่ปรากฏในรายการ

หากคุณเป็นแฟนของ GUI คุณสามารถตรวจสอบMeldที่@Alexanderพูดถึง มันทำงานได้ดีทั้งใน windows และ linux


1

เพื่อรายงานความแตกต่างระหว่าง dirA และ dirB ในขณะเดียวกันก็อัพเดต / ซิงค์

rsync -auv <dirA> <dirB>

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.