โฟลเดอร์ linux merge: rsync?


13

ฉันมีโฟลเดอร์สองชุด

src/
dest/

ฉันต้องการรวมพวกเขาทำต่อไปนี้:

หากไฟล์มีเฉพาะในsrcฉันต้องการที่จะย้ายไปdest

หากไฟล์มีเฉพาะdestฉันต้องการให้ละเว้น IE เพียงอย่างเดียว

หากไฟล์มีทั้งคู่และมีเนื้อหาเหมือนกัน (ขนาดและวันที่เดียวกัน IE) ให้ลบออกsrc

หากไฟล์ที่อยู่ในทั้งสองและไม่ได้มีเนื้อหาเหมือนกันทิ้งในsrcดังนั้นฉันด้วยตนเองสามารถผสานพวกเขา

ควรมีไฟล์จำนวนน้อยมาก (ระหว่าง 0% ถึง 5% ของไฟล์ทั้งหมด) ในหมวดหมู่สุดท้ายนี้ แต่ฉันไม่ทราบวิธีการแยกทั้งในและต่างจากในทั้งสอง แต่แตกต่างกัน

ฉันพยายามที่จะคิดออกว่าจะทำอย่างไรกับrsyncแต่ไม่เป็นประโยชน์

คำตอบ:


17

ฉันทำการทดสอบฟังก์ชันการทำงานที่ จำกัด เท่านั้นดังนั้นโปรดใช้ความระมัดระวังกับคำสั่งนี้ (- พยายามเรียกใช้):

rsync -avPr --ignore-existing --remove-source-files src/ dest

โปรดทราบว่าการติดตาม / เนื่องจากจะมีการคืนค่าเป็น src แทนการคัดลอก src เองซึ่งควรรักษาเส้นทางที่มีอยู่ของคุณ

โดยการใช้แฟล็ก --ignore- ที่มีอยู่ร่วมกับ --remove-source-files คุณจะลบเฉพาะไฟล์จาก src ที่ซิงค์ 'จาก src ไปยังปลายทางนั่นคือไฟล์ที่ไม่เคยมีอยู่ในปลายทางเท่านั้น

สำหรับการลบไฟล์ที่ไม่ซิงค์กันนั่นคือไฟล์ที่มีอยู่แล้วในปลายทาง / ตามที่อยู่ใน src / คุณสามารถใช้:

for file in `find src/ -type f`; do diff $file `echo $file | sed 's/src/dest/'` && rm $file || echo $file; done

หรือ

find src -type f -exec bash -c 'cmp -s "$0" "${0/#src/dest}" && rm "$0"' {} \;

ถ้าชื่อไฟล์อาจมีช่องว่าง / บรรทัดใหม่ / ... เกี่ยวกับความคิดเห็นของ Gilles เกี่ยวกับตัวละครพิเศษนั่นเป็นสิ่งที่ต้องคำนึงถึงและมีวิธีแก้ไขมากมายสิ่งที่ง่ายที่สุดคือการส่งผ่าน -i ถึง rm ซึ่งจะแจ้งเตือนก่อนการลบทั้งหมด โดยมีเงื่อนไขว่า src / หรือพา ธ พาเรนต์ถูกจัดเตรียมเพื่อค้นหาอย่างไรก็ตามพา ธ ที่ผ่านการรับรองโดยสมบูรณ์ควรส่งผลให้ชื่อไฟล์ทั้งหมดถูกจัดการอย่างเหมาะสมโดยทั้งคำสั่ง diff และ rm โดยไม่มีการอ้างถึง


การแก้ไข: คำสั่งนั้นจะไม่ลบไฟล์ออกจาก src หากสำเนาที่เหมือนกันมีอยู่ในปลายทาง
Tok

ใช่ :( นั่นคือส่วนที่ฉันหายากที่จะคิดออก
David Oneill

2
ข่าวดีก็คือคุณสามารถแก้ไขได้อย่างอิสระโดยไม่ต้องยุ่งยากมาก: for file in `find src/ -type f`; do diff $file `echo $file | sed 's/src/dest/'` && rm $file || echo $file; done(คุณสามารถข้ามไปได้|| echo $fileหากคุณต้องการมันรวมอยู่ในความสมบูรณ์)
Tok

Nifty: นั่นคือสิ่งที่ฉันต้องการ แก้ไขเป็นคำตอบของคุณและฉันจะยอมรับมัน!
David Oneill

@Tok: คำสั่งของคุณจะทำให้หายใจไม่ออกในชื่อไฟล์ที่มีอักขระพิเศษ (ช่องว่าง\?*[, เริ่มต้น-) คุณจำเป็นต้องใช้คำพูดสองรอบแทนตัวแปรผ่าน--สาธารณูปโภคก่อนชื่อไฟล์ที่ใช้แทนการแยกการส่งออกของfind … -exec … findด้วยrmคำสั่งในการผสมนี้เป็นสูตรสำหรับภัยพิบัติ
Gilles 'หยุดความชั่วร้าย'

6

พร้อมเพรียงเป็นเครื่องมือที่คุณกำลังมองหา ลอง unison-gtk หากคุณต้องการ gui แต่ฉันไม่คิดว่ามันจะลบไฟล์ที่คล้ายกัน: พร้อมเพรียงพยายามให้ทั้งสองไดเรกทอรีเหมือนกัน อย่างไรก็ตามมันจะง่าย 1) ระบุไฟล์ที่จะคัดลอก; 2) อันไหนที่ต้องการรวมคู่มือ


มันไม่ได้ทำในสิ่งที่ OP ต้องการ แต่ดูเหมือนว่าจะบรรลุเป้าหมายสูงสุดของ OP +1
Ryan C. Thompson

+1 น่าเสียดายที่เซิร์ฟเวอร์ที่ฉันใช้งานอยู่ยังไม่ได้ติดตั้งพร้อมกันและฉันไม่ได้รับอนุญาตให้ติดตั้ง แต่นี่อาจเป็นคำตอบที่ดีสำหรับคนอื่น
David Oneill

1
คุณสามารถดาวน์โหลดปฏิบัติการพร้อมเพรียงจากseas.upenn.edu/~bcpierce/unison//download/... ติดตั้งที่ไหนสักแห่งในไดเรกทอรีบ้านของคุณมันเป็นเพียงไฟล์เดียว
JooMing

2

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

cd src
find . -exec sh -c '
    set -- "/path/to/dest/$0"
    if [ -d "$0" ]; then #  the source is a directory 
      if ! [ -e "$1" ]; then
        mv -- "$0" "$1"  # move whole directory in one go
      fi
    elif ! [ -e "$0" ]; then  # the source doesn't exist after all
      :  # might happen if a whole directory was moved
    elif ! [ -e "$1" ]; then  # the destination doesn't exist
      mv -- "$0" "$1"
    elif [ -f "$1" ] && cmp -s -- "$0" "$1"; then  # identical files
      rm -- "$0"
    fi
  ' {} \;

อีกวิธีหนึ่งที่จะทำสหภาพติดไดเรกทอรีหนึ่งเหนือผู้อื่นเช่นกับfunionfsหรือunionfs ฟิวส์

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