ฉันจะทำให้ 'diff -X' ละเว้นเส้นทางที่ระบุและไม่ใช่ชื่อไฟล์ได้อย่างไร


28

การทำ: diff -r -X <ignore-list> <src-dir> <dest-dir>

ดูเหมือนจะไม่ให้diffละเว้นรายการในถ้าพวกเขาอยู่ในรูปแบบ<ignore-list><dir>/<file>

รายการของแบบฟอร์ม<file> ทำอย่างไรก็ตามได้รับการพิจารณา นี่เป็นปัญหาเนื่องจากฉันอาจมีชื่อไฟล์หลายไฟล์<file>ในไดเรกทอรีย่อยที่แตกต่างกันซึ่งบางไฟล์ไม่ต้องการถูกเพิกเฉย

ดูเหมือนจะไม่มีข้อมูลมากนักเกี่ยวกับไวยากรณ์รูปแบบใน manpage ของdiffทั้งสอง จากสิ่งที่ฉันสามารถบอกได้มันเป็นเพียงชื่อฐานของไฟล์ที่พิจารณาโดย diff (ดูhttp://forums.gentoo.org/viewtopic-t-889788-start-0.htmlหากคุณสนใจ)


มนุษย์diffของ--excludeตัวเลือกเพื่อให้เชี่ย ...
Elouan Keryell-แม้

คำตอบ:


30

รายชื่อไดเรกทอรีควรทำงาน; เช่นนี่คือสิ่งที่ฉันใช้ในสคริปต์ (สมมติว่า gnu diff)

diff -r \
   --exclude="*~" \
   --exclude=".svn" \
   --exclude=".git" \
   --exclude="*.zip*" \
   --exclude="*.gz" \
   --exclude="*.tar" \
   ...etc

... ซึ่งไม่สนใจเนื้อหาของ.svnและ.gitdirs แต่ยังรวมถึงไฟล์แต่ละชื่อ*.zip/ *.gz/ ฯลฯ

แก้ไข:เพื่อกรองพา ธ ของฟอร์มdir_a/file1แต่ยังคงdiffไฟล์ที่มีชื่อไฟล์เหมือนกันเช่นdir_b/file1หรือdir_a/b/file1จากนั้นdiffจะต้องสร้างรายการไฟล์ที่จะต้องสร้าง (ตัวอย่างเช่นการใช้find) และไฟล์เพื่อเปรียบเทียบที่ได้มาจากพา ธ เหล่านี้ เช่นได้รับ

$ find ONE TWO -type f -print 
ONE/a/1.txt
ONE/a/2.txt
ONE/a/b/2.txt
TWO/a/1.txt
TWO/a/2.txt
TWO/a/b/2.txt

คุณสามารถสร้างรายชื่อของไฟล์ที่จะเปรียบเทียบไม่รวมตัวอย่างเช่น*/a/2.txtแต่ยังคงเปรียบเทียบไฟล์อื่น ๆ 2.txtชื่อ เพียงแค่ "ค้นหา" ไฟล์ทั้งหมดยกเว้นONE/a/2.txt(สามารถใช้ regexp ที่นี่เช่น.*/a/2.txt)

$ find ONE -type f \( ! -regex 'ONE/a/2.txt' \) \
    -exec bash -c 'diff -q "${1}" "${2/ONE/TWO}"' - {} {} \;  

ซึ่งผลจะไม่สนใจONE/a/2.txt(และTWO/a/2.txt) แต่ยังคงเปรียบเทียบไฟล์อื่น ๆ ที่ชื่อ2.txt:

diff -q ONE/a/1.txt TWO/a/1.txt
diff -q ONE/a/b/2.txt TWO/a/b/2.txt

แก้ไข:หรือเพิ่มความสนุกด้วยfind(เหลือความสนุกเพิ่มเติมสำหรับการออกกำลังกายสำหรับผู้อ่าน) เลือกไฟล์หรือไดเรกทอรีที่จะแยกออกจากนั้นทำdiffอย่างอื่น:

$ find ONE \( -regex 'ONE/a/2.txt' -o -name b  -prune \)  \
    -o -type f -exec bash -c 'echo diff -q "${1}" "${2/ONE/TWO}"' - {} {} \

ตัวอย่างด้านบนไม่รวมไฟล์เฉพาะ "{top} /a/2.txt", ไดเรกทอรีใด ๆ ที่ชื่อ "b" และทุกอย่างอื่นจะแตกต่างกัน (แทนที่จะใช้ "" อย่างง่าย-name bคุณสามารถใช้ " -regex '.*/b'" - โน้ตได้โดยไม่ต้องต่อท้าย "/")


2
ขอบคุณ แต่ฉันคิดว่าคุณไม่มีจุด การสนับสนุนที่ดูเหมือนจะเกิดขึ้นก็คือเมื่อคุณใช้ 'ชื่อฐาน' อาจเป็นชื่อของไดเรกทอรีหรือไฟล์ ไม่ว่าในกรณีใดก็ตาม diff ไม่สนใจสิ่งที่คุณขอ ปัญหาเกิดขึ้นเมื่อคุณใช้เส้นทาง ตัวอย่างเช่นฉันไม่สามารถรับความแตกต่างในการละเว้น / an / absolute / path / to / a / file หรือ. / a / relative/path/to/a/file
Ash

2
diff --exclude = "/ this / specific / file / that / im / อย่างชัดเจน / ขอร้อง / คุณ / ถึง / ละเว้น" มันจะไม่ทำงาน
Ash

3
ถูกต้องexcludeรูปแบบจะถูกจับคู่กับชื่อไฟล์ '(ตามgnu.org/software/diffutils/manual/html_node/… ); เส้นทางจะไม่ทำงาน (เหมือนในfoo/bar.txt) ในการทำเช่นนั้นคุณอาจต้องเรียกใช้findเพื่อสร้างรายการชื่อไฟล์และหาเส้นทางไปยังไฟล์เพื่อเปรียบเทียบ
ไมเคิล

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

โอเคฉันเห็นสิ่งที่คุณเสนอ แต่ดูเหมือนจะมีปัญหา ฉันต้องพิจารณาไดเรกทอรีเช่นกันไม่ใช่แค่ไฟล์ (เช่น -type f) ทีนี้ในขณะที่คุณยังสามารถตัดออกไฟล์บางไฟล์โดยใช้ regexp ด้วยfindหากอินพุตdiffมีไดเรกทอรีมันจะผ่านและเปรียบเทียบไฟล์ภายในไดเรกทอรีนั้นและไฟล์เหล่านี้บางไฟล์อาจต้องถูกเพิกเฉย .... ดังนั้นคุณจึง กลับไปที่ตาราง 1
Ash

2

diffฉันมีปัญหาเดียวกันดังนั้นฉันสร้างแพทช์ไป แพทช์ยังไม่ได้รับการยอมรับ แต่คุณสามารถสร้างรุ่นของคุณเองdiffกับแพทช์หรือติดตั้งบน Arch Linux กับแพคเกจ

นี่คือdiffแพทช์


1

หากต้องการยกเว้นไดเรกทอรีdirectory/sub-directoryฉันใช้

diff -r <src-dir> <dest-dir> | grep -v directory/sub-directory

อย่างไรก็ตามถึงแม้ว่ามันจะทำงานได้สำหรับการแยกเดี่ยว แต่ก็ไม่ควรจะเป็นไปได้สำหรับรายการที่ไม่สนใจอย่างที่คุณมี


-2
$ diff -rq foo.orig foo | grep -vP 'ignore1/|exclude2/' | awk '{print $2}' | cut -d'/' -f2- | xargs -I{} diff -u foo.orig/{} foo/{}

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