วิธีการซิงค์สองโฟลเดอร์ด้วยเครื่องมือบรรทัดคำสั่ง?


63

เมื่อย้ายไปยัง Linux จาก Windows ฉันต้องการค้นหาซอฟต์แวร์ทางเลือกอื่นสำหรับ Winmerge หรือเรียนรู้เครื่องมือบรรทัดคำสั่งเพื่อเปรียบเทียบและซิงค์สองโฟลเดอร์บน Linux ฉันจะขอบคุณถ้าคุณสามารถบอกวิธีการทำงานต่อไปนี้ในบรรทัดคำสั่ง ... (ฉันได้ศึกษาต่างและ rsync แต่ฉันยังต้องการความช่วยเหลือบางอย่าง)

เรามีสองโฟลเดอร์: "/ home / user / A" และ "/ home / user / B"

โฟลเดอร์ A เป็นสถานที่ที่บันทึกไฟล์และโฟลเดอร์ปกติและโฟลเดอร์ B เป็นโฟลเดอร์สำรองที่ทำหน้าที่เป็นมิเรอร์ที่สมบูรณ์ของโฟลเดอร์ A (ไม่มีการบันทึกหรือแก้ไขโดยตรงจากผู้ใช้ในโฟลเดอร์ B)

คำถามของฉันคือ:

  • จะแสดงรายการไฟล์ที่มีเฉพาะในโฟลเดอร์ B ได้อย่างไร (เช่นสิ่งที่ถูกลบออกจากโฟลเดอร์ A ตั้งแต่การซิงโครไนซ์ครั้งล่าสุด)

  • จะคัดลอกไฟล์ที่มีอยู่ในโฟลเดอร์ B เท่านั้นกลับไปยังโฟลเดอร์ A ได้อย่างไร?

  • วิธีแสดงรายการไฟล์ที่มีอยู่ในทั้งสองโฟลเดอร์ แต่มีการประทับเวลาหรือขนาดต่างกัน (อันที่ถูกแก้ไขในโฟลเดอร์ A ตั้งแต่การซิงโครไนซ์ครั้งล่าสุดฉันต้องการหลีกเลี่ยงการใช้ checksums เนื่องจากมีไฟล์หลายหมื่นไฟล์และมันทำให้กระบวนการช้าเกินไป)

  • จะทำการคัดลอกโฟลเดอร์ A ไปยังโฟลเดอร์ B ได้อย่างไร? ฉันหมายถึงคัดลอกทุกอย่างจากโฟลเดอร์ A ไปยังโฟลเดอร์ B ที่มีเฉพาะในโฟลเดอร์ A และลบทุกอย่างจากโฟลเดอร์ B ที่มีเฉพาะในโฟลเดอร์ B แต่ไม่ต้องแตะไฟล์ที่เหมือนกันในทั้งสองโฟลเดอร์


ทำไมไม่ใช้โปรแกรมสำรองที่เหมาะสมสำหรับสิ่งนี้ ความซ้ำซ้อนเป็นหนึ่งในตัวอย่าง
Qudit

คำตอบ:


88

สิ่งนี้จะนำโฟลเดอร์ A ไปไว้ในโฟลเดอร์ B:

rsync -avu --delete "/home/user/A" "/home/user/B"  

หากคุณต้องการให้เนื้อหาของโฟลเดอร์ A และ Bเหมือนกันให้ใส่/home/user/A/(พร้อมเครื่องหมายทับ) เป็นแหล่งที่มา สิ่งนี้ไม่ได้อยู่ในโฟลเดอร์ A แต่จะมีเนื้อหาทั้งหมดและใส่ไว้ในโฟลเดอร์ B เช่นนี้

rsync -avu --delete "/home/user/A/" "/home/user/B"
  • -a ทำการซิงค์เพื่อรักษาคุณสมบัติของระบบไฟล์ทั้งหมด
  • -v วิ่งอย่างละเอียด
  • -u คัดลอกไฟล์ที่มีเวลาแก้ไขใหม่กว่าเท่านั้น (หรือความแตกต่างของขนาดหากเวลาเท่ากัน)
  • --delete ลบไฟล์ในโฟลเดอร์เป้าหมายที่ไม่มีอยู่ในแหล่งที่มา

Manpage: https://download.samba.org/pub/rsync/rsync.html


7
rsync : เรียกใช้แอป rsync, -a : ทำการซิงค์เพื่อรักษาคุณสมบัติของระบบไฟล์ทั้งหมด, -v : เรียกใช้ verbosely, -z : บีบอัดข้อมูลระหว่างการซิงค์ (ส่งข้อมูลในโหมดบีบอัด), - ลบ : ลบไฟล์ในเป้าหมาย โฟลเดอร์ที่ไม่มีอยู่ในซอร์ส/ home / user / A : โฟลเดอร์ต้นทาง/ home / user / B : โฟลเดอร์
ปลายทาง

สวัสดี SonicARG ฉันลืมที่จะกลับไปที่สิ่งนี้และใส่คำอธิบายโดยสิ้นเชิงขอบคุณที่ส่งคำอธิบายฉันใส่คำตอบของคุณหวังว่าคุณจะไม่รังเกียจ
TuxForLife

6
Rsync มีความหมายเบื้องต้นในการคัดลอกไฟล์ระหว่างคอมพิวเตอร์ต่าง ๆ ตามที่อธิบายไว้ที่นี่สามารถใช้เพื่อวัตถุประสงค์ในการซิงค์ไดเรกทอรีได้เช่นกัน ดังนั้นตัวเลือก z จึงน่าสนใจที่จะลดทราฟฟิกเครือข่ายและเพิ่มประสิทธิภาพของ rsync ระหว่างคอมพิวเตอร์ 2 เครื่อง: (อ่านข้อมูลจากดิสก์ -> บีบอัด) === เครือข่าย ===> (uncompress-> เขียนลงดิสก์) การใช้ - z เพื่อซิงค์ 2 ไดเรกทอรีบนโฮสต์เดียวกันนั้นค่อนข้างงี่เง่าและสิ้นเปลือง cpu cycles ตามที่คุณจะได้รับ (อ่านข้อมูลจากดิสก์ -> บีบอัด -> uncompress -> เขียนลงดิสก์)
GerritCap

@GerritCap ฉันได้ทำการแก้ไขขอขอบคุณสำหรับข้อมูลที่มีค่าของคุณ
TuxForLife

1
ฉันได้ลองคำสั่งแล้ว แต่มันสร้าง sub-dir /home/user/B/Aแทนที่จะเขียนทับเนื้อหาของ A ไปยังเนื้อหาของ B คุณช่วยฉันดูหน่อยได้ไหม?
ลุค

10

คุณสามารถunisonพัฒนาเครื่องมือโดย Benjamin Pierce ที่ U Penn

ให้เราสมมติว่าคุณมีสองไดเรกทอรี

/home/user/Documents/dirA/ และ /home/user/Documents/dirB/

ในการซิงโครไนซ์ทั้งสองนี้คุณสามารถใช้:

~ $unison -ui text /home/user/Documents/dirA/ /home/user/Documents/dirB/

ในผลลัพธ์unisonจะแสดงไดเรกทอรีและไฟล์แต่ละรายการและทุกไฟล์ที่แตกต่างกันในสองไดเรกทอรีที่คุณขอให้ซิงค์ มันจะแนะนำให้ additively ประสาน (ซ้ำแฟ้มในสถานที่ทั้งสองหายไป) ในระยะเริ่มต้นแล้วการสร้างและรักษาต้นไม้ให้ตรงกันในเครื่องของคุณและวิ่งตามมาก็จะดำเนินการประสานความจริง (เช่นถ้าคุณลบไฟล์จาก.../dirAมัน จะถูกลบ.../dirBเช่นกันนอกจากนี้คุณยังสามารถเปรียบเทียบการเปลี่ยนแปลงแต่ละรายการและเลือกที่จะส่งต่อหรือย้อนกลับซิงโครไนซ์ระหว่างสองไดเรกทอรี

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

เพิ่มเติมเกี่ยวกับเรื่องนี้: พร้อมเพรียงกวดวิชาที่เอกสารที่ใช้ประกอบพร้อมเพรียงกัน


1

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

-c, --checksum
       This forces the sender to checksum every regular file using a 128-bit  MD4
       checksum.   It  does this during the initial file-system scan as it builds
       the list of all available files. The receiver then checksums  its  version
       of  each  file  (if  it exists and it has the same size as its sender-side
       counterpart) in order to decide which files need to be updated: files with
       either  a  changed  size  or a changed checksum are selected for transfer.
       Since this whole-file checksumming of all files on both sides of the  con-
       nection  occurs  in  addition to the automatic checksum verifications that
       occur during a file's transfer, this option can be quite slow.

       Note that rsync always verifies that each transferred file  was  correctly
       reconstructed  on  the receiving side by checking its whole-file checksum,
       but that automatic after-the-transfer verification has nothing to do  with
       this  option's  before-the-transfer  "Does  this file need to be updated?"
       check.

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

การตั้งค่า

$ cd /tmp

$ mkdir -p {A,b}/1/2/{3,4}

$ echo "\___________from A" | \
      tee A/1/2/x  | tee A/1/2/3/y  | tee A/1/2/4/z  | \
  tr A b | \
      tee b/1/2/x  | tee b/1/2/3/y  | tee b/1/2/4/z  | \
      tee b/1/2/x0 | tee b/1/2/3/y0 >     b/1/2/4/z0

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from b
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from b
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from b
b/1/2/x0
\___________from b

rsync ที่คัดลอกไม่ได้เนื่องจากไฟล์ทั้งหมดมีขนาดและเวลาที่เท่ากัน

$ rsync -avu A/ b
building file list ... done

sent 138 bytes  received 20 bytes  316.00 bytes/sec
total size is 57  speedup is 0.36

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from b
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from b
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from b
b/1/2/x0
\___________from b    

rsync ที่ทำงานอย่างถูกต้องเพราะมันเปรียบเทียบ checksums

$ rsync -cavu A/ b
building file list ... done
1/2/x
1/2/3/y
1/2/4/z

sent 381 bytes  received 86 bytes  934.00 bytes/sec
total size is 57  speedup is 0.12

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from A
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from A
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from A
b/1/2/x0
\___________from b

-c และ -u ทำงานร่วมกันได้ดีหรือไม่
Sergey Korzhov

@SergeyKorzhov มันทำ `-u 'ยังคงทำงานตามปกติเพื่ออัปเดตเฉพาะในกรณีที่ปลายทางไม่ใหม่
Bruno Bronosky

1

นี่คือสิ่งที่ฉันใช้ในการสำรองไฟล์ส่วนบุคคลที่ฉันไม่สนใจเกี่ยวกับทุกสิ่งที่ครอบคลุม-aและต้องการพิมพ์ข้อมูลที่มีประโยชน์มากขึ้น

rsync -rtu --delete --info=del,name,stats2 "/home/<user>/<src>/" "/run/media/<user>/<drive>/<dst>"

จากหน้าrsync :

-r, --recursive
นี้จะบอก rsync เพื่อคัดลอกไดเรกทอรีซ้ำ

-t, --times
สิ่งนี้บอก rsync เพื่อถ่ายโอนเวลาการแก้ไขพร้อมกับไฟล์และอัพเดตบนระบบรีโมต

-u, --update
สิ่งนี้บังคับให้ rsync ข้ามไฟล์ใด ๆ ที่มีอยู่ในปลายทางและมีเวลาแก้ไขที่ใหม่กว่าไฟล์ต้นฉบับ (หากไฟล์ปลายทางที่มีอยู่มีเวลาแก้ไขเท่ากับไฟล์ต้นฉบับไฟล์นั้นจะได้รับการอัปเดตหากขนาดต่างกัน)

- ลบคำสั่ง
นี้บอก rsync ให้ลบไฟล์ที่ไม่เกี่ยวข้องออกจากด้านที่รับ (ไฟล์ที่ไม่ได้อยู่ในฝั่งที่ส่ง) แต่สำหรับไดเรกทอรีที่กำลังซิงโครไนซ์เท่านั้น

--info = FLAGS
ตัวเลือกนี้ช่วยให้คุณสามารถควบคุมการแสดงผลข้อมูลที่ต้องการได้อย่างละเอียด

จาก rsync --info=help

DEL        Mention deletions on the receiving side  
NAME       Mention 1) updated file/dir names, 2) unchanged names  
STATS      Mention statistics at end of run (levels 1-3)

ในขณะที่ชัดเจนน้อยกว่านี้ดูเหมือนจะเทียบเท่าและสั้นกว่า:

rsync -rtuv --delete --info=stats2 "/home/<user>/<src>/" "/run/media/<user>/<drive>/<dst>"

-v, --verbose
เดี่ยว -v จะให้ข้อมูลเกี่ยวกับไฟล์ที่ถูกถ่ายโอนและสรุปโดยย่อในตอนท้าย [stats1]


0

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


2
ใช้งานได้เฉพาะในกรณีที่คุณต้องการเพิ่มทุกอย่างในการควบคุมเวอร์ชัน มันยังบังคับให้การเปลี่ยนแปลงทุกอย่างที่เคยถูกจัดเก็บไว้อย่างถาวรซึ่งอาจไม่เป็นที่ต้องการ
Qudit

@Qudit นั่นเป็นความจริงแม้ว่าจะเป็นไปได้ผ่านการโคลนเพื่อ จำกัด ประวัติ แต่การ จำกัด ประวัติไม่ได้ดำเนินการใน Git (ยัง?) โดยค่าเริ่มต้น
switch87

@ switch87 ใช่ฉันรู้ว่าคุณสามารถลบการคอมมิชชันเก่าได้ การควบคุมเวอร์ชันไม่ใช่โซลูชันที่เหมาะสมสำหรับการสำรองข้อมูลทั่วไปแม้ว่าโดยเฉพาะอย่างยิ่งหากมีไฟล์ไบนารีขนาดใหญ่
Qudit

คำถามของเขาสำหรับการสำรองข้อมูลท้องถิ่น แต่ถ้าคุณใช้สำหรับการสำรองข้อมูลระยะไกลคุณยังสามารถใช้ภาคผนวก git สำหรับไฟล์ที่ใหญ่กว่า สำหรับการสำรองข้อมูลในเครื่องนี่ไม่ใช่ปัญหา
switch87

2
@ switch87 นี่ควรเป็นความเห็นต่อ Q และไม่ใช่คำตอบเนื่องจากไม่ได้อธิบายว่าคุณใช้ git เพื่อทำการสำรองข้อมูลได้อย่างไร
slm

0

คุณสามารถใช้วิธีนี้:

rsync -avu --delete /home/user/A/* /home/user/B/

วิธีนี้คุณจะคัดลอกเนื้อหาของโฟลเดอร์ A ไปยังโฟลเดอร์ B ไม่ใช่เนื้อหาของโฟลเดอร์ A

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