เปรียบเทียบ 2 ไดเรกทอรีและคัดลอกความแตกต่างในไดเรกทอรีที่ 3


32

ใช้ Ubuntu 12.04 ฉันต้องการเปรียบเทียบ 2 ไดเรกทอรีพูด folder1 / และ folder2 / และคัดลอกไฟล์ใด ๆ ที่แตกต่างกับ folder3 / นอกจากนี้ยังมีไฟล์ซ้อนกันดังนั้นควรคัดลอกไดเรกทอรีย่อยที่ตรงกันเช่นกัน

มีคำสั่งเดียวที่จะช่วยฉันได้ไหม ฉันสามารถเรียกใช้รายการไฟล์ที่เปลี่ยนแปลงทั้งหมดได้:

rsync -rcnC --out-format="%f" folder1/ folder2/

แต่ rsync ดูเหมือนจะไม่มีความสามารถในการ "ส่งออก" ไฟล์เหล่านี้ในไดเรกทอรีเป้าหมายที่แตกต่างกัน ฉันสามารถไพพ์รายการไปยัง cp หรือโปรแกรมอื่น ๆ เพื่อให้คัดลอกไฟล์ในขณะที่สร้างไดเรกทอรีได้หรือไม่? ตัวอย่างเช่นฉันพยายาม

rsync -rcnC --out-format="%f" folder1/ folder2/ | xargs cp -t folder3/

แต่นั่นจะไม่เก็บไดเรกทอรีไว้เช่นกันมันก็แค่คัดลอกไฟล์ทั้งหมดใน folder3 /


ฉันอาจจะใช้การรวมกันของdiff -qrและawkเพื่อสร้างรายการจากนั้นrsync...
ewwhite

ฉันจะใช้ rsync กับรายการได้อย่างไร
periklis

ฉันจะเรียกใช้ for-loop หรือใช้rsync --include-from=FILEตัวเลือก
ewwhite

(ไม่ต้องขี้เกียจ ... ) แต่โซลูชัน rsyncด้านล่างนั้นสวยงาม
ewwhite

คำตอบ:


37

ใช้ - เปรียบเทียบ-dest

จากหน้าคน:

--compare-dest = DIR - ตัวเลือกนี้สั่งให้ rsync ใช้ DIR บนเครื่องปลายทางเป็นลำดับชั้นเพิ่มเติมเพื่อเปรียบเทียบไฟล์ปลายทางกับการถ่ายโอน (ถ้าไฟล์หายไปในไดเรกทอรีปลายทาง) หากพบไฟล์ใน DIR ที่เหมือนกับไฟล์ของผู้ส่งไฟล์จะไม่ถูกถ่ายโอนไปยังไดเรกทอรีปลายทาง สิ่งนี้มีประโยชน์สำหรับการสร้างการสำรองข้อมูลแบบกระจัดกระจายของไฟล์ที่เปลี่ยนแปลงจากการสำรองข้อมูลก่อนหน้า

ตรวจสอบไวยากรณ์ของคุณด้วย --dry-run

rsync -aHxv --progress --dry-run --compare-dest=folder2/ folder1/ folder3/

จากนั้นเมื่อคุณพอใจกับผลลัพธ์:

rsync -aHxv --progress  --compare-dest=folder2/ folder1/ folder3/

ลิงค์นี้มีคำอธิบายที่ดีเกี่ยวกับขอบเขตการเปรียบเทียบปลายทาง


1
ขอบคุณสำหรับสิ่งนี้ฉันไม่เข้าใจคำอธิบาย man page ของพารามิเตอร์นี้ สำหรับทุกคนที่สนใจฉันได้ทำกับrsync -rcC --compare-dest=folder2/ folder1/ folder3/
periklis

บันทึกย่อสำหรับผู้ใช้ OsX ฉันมีrsync version 3.1.1 protocol version 31ในพื้นที่ของฉันและ rsync ไม่เข้าใจ~/เส้นทางสำหรับ--compare-destพารามิเตอร์
Jevgeni Smirnov

3
สำหรับฉัน--compare-destต้องมีเส้นทางที่แน่นอน
palswim

ไม่ได้ผลกับฉันด้วยตัวเลือกของผู้เขียนหรือ OP นั่นคือfonts/Makefile.inไฟล์ที่ส่งออกซึ่งเหมือนกันทั้งในfolder2และfolder1dirs
Hi-Angel

3

สคริปต์เล็ก ๆ นี้ควรทำงาน:

folder1="firsts_folder/"
folder2="second_folder/"
folder3="target_folder"
for x in `rsync -rcnC --out-format="%n"  $folder1 $folder2`
    do
        if [ -d "$folder1/$x" ]; then
            mkdir -p "$folder3/$x"
        else
            cp -frv $folder1/$x $folder3/$x
        fi
done

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

แก้ไข

นี่จะเป็นหนึ่งคำสั่งคำสั่งของคุณปรับเปลี่ยนเล็กน้อย แต่มันจะสร้างภายใต้folder1 folder3และมันใช้งานไม่ได้กับเส้นทางแบบเต็ม แต่สคริปต์ด้านบนไม่สามารถใช้กับเส้นทางแบบเต็มได้

rsync -rcnC --out-format="\"%f\"" folder1/ folder2/ | xargs cp --parents -rfvt folder3/

ผมใช้\"ในการrsyncที่จะทำให้มันทำงานกับไฟล์และไดเรกทอรีที่มีช่องว่าง ทดสอบบน Ubuntu 10.04 หวังว่ามันจะช่วย


ขอบคุณสำหรับสิ่งนี้ฉันหวังว่าจะมีคำสั่งเดียวอยู่
periklis

2
rsync -rcnC --out-format="%f" . ../folder2/ |xargs cp --parents -rt ../folder3/

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

นี่เป็นตัวเลือกที่ช้ากว่าแต่ฉันเชื่อว่าตรงกับความต้องการของคุณและสามารถเรียกใช้งานได้โดยใช้ชื่อไดเรกทอรีที่ไม่เกี่ยวข้อง:

rsync -rcnC --out-format="%n" folder1/ folder2/ |grep -vP "/$" |xargs -I{} rsync -R folder1/./{} folder3/

ฉันออกจากrsyncคำสั่งดั้งเดิมของคุณคนเดียวเพราะคุณบอกว่ามันให้รายชื่อไฟล์ที่ถูกต้อง (และไฟล์ทดสอบของฉันแตกต่างจากของคุณอย่างเห็นได้ชัดดังนั้นฉันไม่สามารถพูดได้อย่างแน่นอนว่าฉันจะได้รับรายชื่อไฟล์ที่ถูกต้อง กับมัน)

จะมีการลบชื่อไดเรกทอรีจากการส่งออกของgreprsync

การส่งออกของgrepแล้วประปาไปยังอีกโดยใช้rsync xargsในพระรามfolder1/./{}พิเศษ./จะใช้ในการบอก rsync เพื่อสร้างไดเรกทอรีญาติเริ่มต้นด้วยการละเว้น./{} folder1/ในคำอื่น ๆ folder3/folder1/ก็หลีกเลี่ยงการสร้าง

ฉันสามารถทดสอบได้บน CentOS 6.4 เท่านั้น แต่ AFAIK ควรใช้งานได้เหมือนกันใน Ubuntu 12.04

แก้ไข: ฉันควรทราบว่าคำตอบของsmithianดีกว่าไม่ต้องสงสัย แต่ฉันต้องการที่จะแทงด้วยrsyncคำสั่งเดิมของคุณในการเจรจาต่อรองเพราะมันให้ผลลัพธ์ที่ต้องการ

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