rsync file tertentu, tidak termasuk sisanya, mengabaikan direktori .svn /, secara rekursif

19

Saya menggunakan rsyncuntuk menyalin beberapa file dari berbagi ke yang lain.

Secara rekursif, saya perlu:

  • Hapus file di tujuan yang dihapus dari asal
  • Hanya sinkronisasi .phpdan .jsfile
  • Kecualikan setiap jenis file lainnya
  • Jangan hapus .svn/direktori di tujuan

Jika saya menggunakan ini:

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

Maka rsynctidak rekursif karena exclude="*"mengecualikan semua file tetapi juga folder.

Jika saya tambahkan --include="*/"maka .svn/direktori akan dihapus (itu juga akan disertakan).

Bagaimana saya bisa menyelesaikan dilema peledakan pikiran ini?

uname -a:

Linux tux 3.9.2-1-ARCH # 1 SMP PREEMPT Sabtu 11 Mei 20:31:08 CEST 2013 x86_64 GNU / Linux

rsync Versi: kapan:

rsync 3.0.9-6
canolucas
sumber

Jawaban:

13

Upaya 1 (tidak berhasil)

Anda harus memasukkan direktori di samping file:

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

Usaha ke-2

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

data uji

Saya menulis skrip ini untuk membuat beberapa sampel data untuk menguji ini. Berikut script yang, 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

Menjalankannya menghasilkan direktori berikut:

sumber dir

$ 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

tujuan dir

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

Menjalankan rsyncperintah di atas :

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

Menghasilkan 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

Mengapa ini berhasil?

Bagian kunci dari skrip ini adalah untuk memanfaatkan kemampuan filter dari rsync. Filter memungkinkan Anda untuk menghapus file dari set yang cocok di berbagai titik dalam perintah. Jadi dalam kasus kami, kami memfilter file apa pun yang cocok dengan polanya */.svn*. Pengubah-rs_ memberi tahu filter bahwa kami ingin memfilter baik di sisi sumber maupun sisi target.

kutipan dari bagian CATATAN FILTER pada halaman manual rsync

  • Sebuah s digunakan untuk menunjukkan bahwa aturan tersebut berlaku untuk sisi pengirim. Ketika aturan mempengaruhi sisi pengiriman, itu mencegah file ditransfer. Defaultnya adalah aturan memengaruhi kedua sisi kecuali --delete-excludedditentukan, dalam hal ini aturan default hanya menjadi sisi pengirim. Lihat juga aturan sembunyikan (H) dan tunjukkan (S), yang merupakan cara alternatif untuk menentukan sisi-pengiriman termasuk / tidak termasuk.

  • Sebuah r digunakan untuk menunjukkan bahwa aturan tersebut berlaku untuk sisi penerima. Ketika aturan mempengaruhi sisi penerima, itu mencegah file dari dihapus. Lihat pengubah s untuk info lebih lanjut. Lihat juga aturan proteksi (P) dan risiko (R), yang merupakan cara alternatif untuk menetapkan / mengecualikan sisi penerima.

Lihat man rsync untuk lebih jelasnya.

Kiat untuk mencari tahu ini (petunjuk menggunakan --dry-run )

Sambil menjelaskan bagaimana melakukan ini, saya pikir saya akan menyebutkan --dry-runberalih ke rsync. Sangat berguna untuk melihat apa yang akan terjadi tanpa rsyncbenar - benar terjadi.

Sebagai contoh

Menggunakan perintah berikut akan melakukan uji coba dan menunjukkan kepada kita logika keputusan di belakang 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)

Dalam output di atas Anda dapat melihat bahwa ./svndirektori dilindungi oleh aturan filter kami. Wawasan berharga untuk debugging rsync.

Referensi

slm
sumber
Sudah mencoba ini, seperti yang saya katakan di atas. Jika saya melakukan ini, maka direktori .SVN juga disertakan (kemungkinan besar dihapus, karena tidak ada dalam asal, atau dimodifikasi). Sangat penting untuk membiarkan direktori .SVN tidak tersentuh. Terima kasih sudah mencoba! :)
canolucas
-C seharusnya mengabaikan ".SVN /", tetapi include="*/"memasukkannya
canolucas
Kamu benar. Seharusnya .svn, mengedit jawabannya. Lagi pula, setelah mengganti nama masalah tetap ada. -Cdan include="*/"sepertinya bukan teman yang sangat dekat :(
canolucas
10

Oke, setelah beberapa kali coba saya bereskan ini:

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

Terima kasih

canolucas
sumber
Jawaban yang bagus Filter saya melindungi .svn/dir dari --prune-empty-dirsdalam kasus mereka kosong. Pendekatan lain, yang ini menduplikasi direktori kosong:rsync -vaiz --delete --exclude=.svn/ --include='*.php' --include='*.js' --include='*/' --exclude='*' /origin /destination
canolucas
Kunci dari pendekatan saya adalah --exclude=.svn/sebelum --include's
canolucas
Jawaban yang bagus juga. Saya akan menyarankan pengecualian = '. Svn /' tapi saya pikir Anda ingin menggunakan -C. Senang Anda menemukannya!
slm
0

Meskipun ini tidak menggunakan rsync, pilihan lain adalah menggunakan find dan cpio. Misalnya saya punya direktori bernama Foto dan itu tahun dan bulan.

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

Tapi di sini saya punya jpg, dng, xml dan hal-hal lain dan saya hanya ingin jpg jadi saya akan melakukan ini

"cd" ke direktori di atas direktori Photos lalu:

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

Dan pergilah

/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

Anda dapat menggunakan metode ini untuk banyak hal, bertahun-tahun yang lalu ini adalah bagaimana kami akan menyalin / filesystem ketika pindah ke disk yang lebih besar karena akan menyalin file perangkat.

lxtwin
sumber
Itu tidak menjawab pertanyaan.
RalfFriedl
Itu terjadi jika ia menggunakan: find / origin -type f (-name " .php" -o -name " .js") -print | cpio -pdmvu / tujuan Hanya file * .php dan * .js yang ada di direktori target.
lxtwin