rsync ไฟล์บางไฟล์ไม่รวมส่วนที่เหลือโดยไม่สนใจ. svn / directory ซ้ำ


19

ฉันใช้rsyncเพื่อคัดลอกไฟล์บางไฟล์จากการแชร์ไปยังไฟล์อื่น

ฉันจำเป็นต้อง:

  • ลบไฟล์ที่ปลายทางที่ถูกลบออกจากจุดกำเนิด
  • ซิงค์.phpและ.jsไฟล์เท่านั้น
  • ยกเว้นไฟล์ประเภทอื่นทุกประเภท
  • อย่าลบ.svn/ไดเรกทอรีที่ปลายทาง

ถ้าฉันใช้สิ่งนี้:

rsync -zavC --delete --include='*.php' --include='*.js' --exclude="*" \
    /origin /destination

จากนั้นrsyncจะไม่เรียกซ้ำเนื่องจากexclude="*"ไม่รวมไฟล์ทั้งหมด แต่ยังรวมถึงโฟลเดอร์

ถ้าฉันเพิ่ม--include="*/"แล้ว.svn/ไดเรกทอรีจะถูกลบ (รวมอยู่ด้วย)

ฉันจะแก้ไขปัญหานี้ได้อย่างไร?

uname -a:

Linux tux 3.9.2-1-ARCH # 1 SMP PREEMPT Sat 11 พฤษภาคม 20:31:08 CEST 2013 x86_64 GNU / Linux

rsync รุ่น:

rsync 3.0.9-6

คำตอบ:


13

ความพยายามครั้งที่หนึ่ง (ไม่ทำงาน)

คุณต้องรวมไดเรกทอรีเพิ่มเติมจากไฟล์:

rsync -zavC --delete --include '*/' --include='*.php' --include='*.js' \
     --exclude="*" /media/datacod/Test/ /home/lucas/Desktop/rsync/

ครั้งที่สอง

rsync -avzC --filter='-rs_*/.svn*' --include="*/" --include='*.js' \
     --include='*.php' --exclude="*" --delete dir1/ dir2/

ข้อมูลการทดสอบ

ฉันเขียนสคริปต์นี้เพื่อสร้างข้อมูลตัวอย่างเพื่อทดสอบ นี่คือสคริปต์setup_svn_sample.bash:

#!/bin/bash

# setup .svn dirs
mkdir -p dir{1,2}/dir{1,2,3,4}/.svn

# fake data under .svn
mkdir -p dir1/dir{1,2,3,4}/.svn/origdir
mkdir -p dir2/dir{1,2,3,4}/.svn/keepdir

# files to not sync
touch dir1/dir{1,2,3,4}/file{1,2}

# files to sync
touch dir1/dir{1,2,3,4}/file1.js
touch dir1/dir{1,2,3,4}/file1.php

การรันมันจะสร้างไดเร็กตอรี่ต่อไปนี้:

แหล่งที่มา

$ tree -a dir1
dir1
|-- dir1
|   |-- file1
|   |-- file1.js
|   |-- file1.php
|   |-- file2
|   `-- .svn
|       `-- origdir
|-- dir2
|   |-- file1
|   |-- file1.js
|   |-- file1.php
|   |-- file2
|   `-- .svn
|       `-- origdir
|-- dir3
|   |-- file1
|   |-- file1.js
|   |-- file1.php
|   |-- file2
|   `-- .svn
|       `-- origdir
`-- dir4
    |-- file1
    |-- file1.js
    |-- file1.php
    |-- file2
    `-- .svn
        `-- origdir

ปลายทาง dir

$ tree -a dir2
dir2
|-- dir1
|   `-- .svn
|       `-- keepdir
|-- dir2
|   `-- .svn
|       `-- keepdir
|-- dir3
|   `-- .svn
|       `-- keepdir
`-- dir4
    `-- .svn
        `-- keepdir

เรียกใช้rsyncคำสั่งด้านบน:

rsync -avzC --filter='-rs_*/.svn*' --include="*/" --include='*.js' \
     --include='*.php' --exclude="*" --delete dir1/ dir2/
sending incremental file list
dir1/file1.js
dir1/file1.php
dir2/file1.js
dir2/file1.php
dir3/file1.js
dir3/file1.php
dir4/file1.js
dir4/file1.php

sent 480 bytes  received 168 bytes  1296.00 bytes/sec
total size is 0  speedup is 0.00

ผลลัพธ์ dir2 afterards:

$ tree -a dir2
dir2
|-- dir1
|   |-- file1.js
|   |-- file1.php
|   `-- .svn
|       `-- keepdir
|-- dir2
|   |-- file1.js
|   |-- file1.php
|   `-- .svn
|       `-- keepdir
|-- dir3
|   |-- file1.js
|   |-- file1.php
|   `-- .svn
|       `-- keepdir
`-- dir4
    |-- file1.js
    |-- file1.php
    `-- .svn
        `-- keepdir

ทำไมมันทำงาน

rsyncชิ้นส่วนที่สำคัญในการสคริปต์นี้คือการทำให้การใช้ความสามารถของตัวกรอง ตัวกรองอนุญาตให้คุณลบไฟล์ออกจากชุดที่ตรงกันที่จุดต่าง ๆ ในคำสั่ง ดังนั้นในกรณีที่เรากำลังกรองแฟ้มใด ๆ */.svn*ที่ตรงกับรูปแบบ ตัวดัดแปลง-rs_บอกตัวกรองว่าเราต้องการกรองทั้งด้านต้นทางและฝั่งเป้าหมาย

ตัดตอนมาจากส่วน FILTER NOTES ของ man page ของ rsync

  • sถูกนำมาใช้เพื่อแสดงให้เห็นว่ากฎนำไปใช้ในด้านการส่ง เมื่อกฎส่งผลกระทบต่อด้านการส่งมันจะป้องกันไม่ให้ไฟล์ถูกถ่ายโอน ค่าเริ่มต้นสำหรับกฎที่จะส่งผลกระทบต่อทั้งสองฝ่ายเว้นแต่ว่า --delete-excludedมีการระบุไว้ในกรณีนี้กฎเริ่มต้นจะกลายเป็นฝั่งผู้ส่ง ดูเพิ่มเติมที่กฎซ่อน (H) และการแสดง (S) ซึ่งเป็นอีกวิธีหนึ่งในการระบุการรวม / แยกด้านส่ง

  • R ถูกนำมาใช้เพื่อแสดงให้เห็นว่ากฎนำไปใช้ในด้านการรับ เมื่อกฎมีผลกระทบกับด้านการรับมันจะป้องกันไฟล์จากการถูกลบ ดูตัวแก้ไข s สำหรับข้อมูลเพิ่มเติม ดูเพิ่มเติมที่กฎการป้องกัน (P) และความเสี่ยง (R) ซึ่งเป็นอีกวิธีหนึ่งในการระบุการรวม / ไม่รวมตัวรับสัญญาณ

ดูman rsyncสำหรับรายละเอียดเพิ่มเติม

เคล็ดลับในการหาสิ่งนี้ (แนะนำโดยใช้--dry-run)

ในขณะที่การอธิบายวิธีการทำเช่นนี้ฉันคิดว่าฉันพูดถึงการสลับไป--dry-run rsyncมันมีประโยชน์อย่างมากในการเห็นสิ่งที่จะเกิดขึ้นโดยไม่ต้องเกิดขึ้นrsyncจริง

ตัวอย่างเช่น

การใช้คำสั่งต่อไปนี้จะทำการทดสอบและแสดงตรรกะการตัดสินใจให้เราทราบrsync:

rsync --dry-run -avvzC --filter='-rs_*/.svn*' --include="*/" \
     --include='*.js' --include='*.php' --exclude="*" --delete dir1/ dir2/
sending incremental file list
[sender] showing directory dir3 because of pattern */
[sender] showing directory dir2 because of pattern */
[sender] showing directory dir4 because of pattern */
[sender] showing directory dir1 because of pattern */
[sender] hiding file dir1/file1 because of pattern *
[sender] showing file dir1/file1.js because of pattern *.js
[sender] hiding file dir1/file2 because of pattern *
[sender] showing file dir1/file1.php because of pattern *.php
[sender] hiding directory dir1/.svn because of pattern */.svn*
[sender] hiding file dir2/file1 because of pattern *
[sender] showing file dir2/file1.js because of pattern *.js
[sender] hiding file dir2/file2 because of pattern *
[sender] showing file dir2/file1.php because of pattern *.php
[sender] hiding directory dir2/.svn because of pattern */.svn*
[sender] hiding file dir3/file1 because of pattern *
[sender] showing file dir3/file1.js because of pattern *.js
[sender] hiding file dir3/file2 because of pattern *
[sender] showing file dir3/file1.php because of pattern *.php
[sender] hiding directory dir3/.svn because of pattern */.svn*
[sender] hiding file dir4/file1 because of pattern *
[sender] showing file dir4/file1.js because of pattern *.js
[sender] hiding file dir4/file2 because of pattern *
[sender] showing file dir4/file1.php because of pattern *.php
[sender] hiding directory dir4/.svn because of pattern */.svn*
delta-transmission disabled for local transfer or --whole-file
[generator] risking directory dir3 because of pattern */
[generator] risking directory dir2 because of pattern */
[generator] risking directory dir4 because of pattern */
[generator] risking directory dir1 because of pattern */
[generator] protecting directory dir1/.svn because of pattern */.svn*
dir1/file1.js
dir1/file1.php
[generator] protecting directory dir2/.svn because of pattern */.svn*
dir2/file1.js
dir2/file1.php
[generator] protecting directory dir3/.svn because of pattern */.svn*
dir3/file1.js
dir3/file1.php
[generator] protecting directory dir4/.svn because of pattern */.svn*
dir4/file1.js
dir4/file1.php
total: matches=0  hash_hits=0  false_alarms=0 data=0

sent 231 bytes  received 55 bytes  572.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

ในผลลัพธ์ข้างต้นคุณจะเห็นว่า./svnไดเรกทอรีได้รับการคุ้มครองตามกฎตัวกรองของเรา rsyncข้อมูลเชิงลึกที่มีคุณค่าสำหรับการแก้จุดบกพร่อง

อ้างอิง


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

- C ควรละเว้น ".SVN /" แต่include="*/"รวมไว้ด้วย
canolucas

คุณพูดถูก ควรจะ.svnแก้ไขคำตอบ อย่างไรก็ตามหลังจากเปลี่ยนชื่อปัญหายังคงอยู่ -Cและinclude="*/"ดูเหมือนจะไม่เป็นเพื่อนสนิทกันมาก :(
canolucas

10

ตกลงหลังจากลองหลายครั้งฉันก็เรียงมัน:

rsync -vaiz --delete --exclude=.svn/ --include='*.php' --include='*.js' \
    --include='*/' --exclude='*' --prune-empty-dirs \
    --filter "protect .svn/" /origin /destination

ขอขอบคุณ


คำตอบที่ดี ตัวกรองของฉันปกป้อง.svn/dirs จาก--prune-empty-dirsในกรณีที่ว่างเปล่า อีกวิธีหนึ่งอันนี้ทำสำเนา dirs ว่างเปล่า:rsync -vaiz --delete --exclude=.svn/ --include='*.php' --include='*.js' --include='*/' --exclude='*' /origin /destination
canolucas

ที่สำคัญของวิธีการของฉันคือการ--exclude=.svn/ก่อน--include's
canolucas

คำตอบที่ดีเช่นกัน ผมจะแนะนำไม่รวม = 'SVN /' -Cแต่ฉันคิดว่าคุณต้องการที่จะใช้ ดีใจที่คุณคิดออก!
slm

0

แม้ว่านี่จะไม่ได้ใช้ rsync ตัวเลือกอื่นคือการใช้ find และ cpio ตัวอย่างเช่นฉันมีไดเรกทอรีที่เรียกว่า Photos และปีและเดือน

Photos
├── 2002
   ├── 2002-03
      ├── 2002-03-30
      ├── 2002-03-31
      └── 2002-03-31-02
   ├── 2002-04
      ├── 2002-04-01
      ├── 2002-04-01-03
      ├── 2002-04-07
      ├── 2002-04-21
      ├── 2002-04-22
      ├── 2002-04-22-02
      └── 2002-04-27
   ├── 2002-05
      ├── 2002-05-02
      ├── 2002-05-03

แต่ที่นี่ฉันมี jpg, dng, xml และสิ่งอื่น ๆ และฉันต้องการเพียงแค่ jpg ดังนั้นฉันจะทำสิ่งนี้

"cd" ไปยังไดเร็กทอรีด้านบนไดเร็กทอรี Photos จากนั้น:

find Photos -type f -name "*jpg" -print | cpio -pdmvu /fast

และปิดมันไป

/fast/Photos/2002/2002-04/2002-04-22/bath problem.jpg
/fast/Photos/2002/2002-04/2002-04-22-02/full bath.jpg
/fast/Photos/2002/2002-07/2002-07-10/Broken Top.jpg
/fast/Photos/2002/2002-12/2002-12-28/101-0125_IM~~G.jpg
/fast/Photos/2002/2002-12/2002-12-28/small-101-0125_IM~~G.jpg
/fast/Photos/2003/2003-01/2003-01-19/k1.jpg
/fast/Photos/2003/2003-01/2003-01-19/k2.jpg
/fast/Photos/2003/2003-02/2003-02-23/quinn.jpg
/fast/Photos/2003/2003-05/2003-05-04/all.jpg
/fast/Photos/2003/2003-05/2003-05-09/100_0015_r1.jpg
/fast/Photos/2003/2003-05/2003-05-09/100_0006_2_r1.jpg
/fast/Photos/2003/2003-05/2003-05-09/100_0006_r1.jpg
/fast/Photos/2003/2003-05/2003-05-09/100_0007_2_r1.jpg

คุณสามารถใช้วิธีนี้กับสิ่งต่างๆมากมายเมื่อหลายปีก่อนนี่คือวิธีที่เราจะคัดลอกระบบไฟล์ / เมื่อย้ายไปยังดิสก์ขนาดใหญ่เช่นเดียวกับที่มันจะคัดลอกไฟล์อุปกรณ์


ไม่ตอบคำถาม
RalfFriedl

มันจะทำอย่างไรถ้าเขาใช้: find / origin -type f (-name " .php" -o -name " .js") -print | cpio -pdmvu / destination เฉพาะไฟล์ * .php และ * .js เท่านั้นที่จะอยู่ในไดเรกทอรีเป้าหมาย
lxtwin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.