sincronizzare determinati file, escluso il resto, ignorando ricorsivamente la directory .svn /


19

Sto usando rsyncper copiare alcuni file da una condivisione a un'altra.

Ricorsivamente, devo:

  • Elimina i file nella destinazione che sono stati rimossi dall'origine
  • Solo sincronizzazione .phpe .jsfile
  • Escludere ogni altro tipo di file
  • Non eliminare le .svn/directory nella destinazione

Se uso questo:

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

Quindi rsyncnon è ricorsivo perché exclude="*"esclude tutti i file ma anche le cartelle.

Se aggiungo, --include="*/"la .svn/directory viene eliminata (viene inclusa anche).

Come posso risolvere questo dilemma devastante?

uname -a:

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

rsync versione:

rsync 3.0.9-6

Risposte:


13

1o tentativo (non ha funzionato)

È necessario includere le directory oltre ai file:

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

2o tentativo

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

dati di test

Ho scritto questo script per creare alcuni dati di esempio su cui testarlo. Ecco quello script 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

L'esecuzione produce le seguenti directory:

fonte 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

destinazione dir

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

Eseguendo il rsynccomando sopra :

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

Afterard risultanti dir2:

$ 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

Perché funziona

Il pezzo chiave di questo script è utilizzare la capacità di filtri di rsync. I filtri consentono di rimuovere i file dal set corrispondente in vari punti del comando. Quindi nel nostro caso stiamo filtrando tutti i file che corrispondono al modello */.svn*. I modificatori -rs_indicano al filtro che vogliamo filtrare sia sul lato sorgente che sul lato target.

estratto dalla sezione NOTE SUL FILTRO della pagina man di rsync

  • Una s viene utilizzata per indicare che la regola si applica al lato di invio. Quando una regola influisce sul lato di invio, impedisce il trasferimento dei file. L'impostazione predefinita prevede che una regola influisca su entrambi i lati, a meno che non sia --delete-excludedstata specificata, nel qual caso le regole predefinite diventano solo lato mittente. Vedi anche le regole hide (H) e show (S), che sono un modo alternativo per specificare le inclusioni / esclusioni sul lato mittente.

  • Una r è usata per indicare che la regola si applica al lato ricevente. Quando una regola influisce sul lato ricevente, impedisce l'eliminazione dei file. Vedi il modificatore s per maggiori informazioni. Vedi anche le regole di protezione (P) e rischio (R), che sono un modo alternativo per specificare le inclusioni / esclusioni dal lato destinatario.

Vedi man rsync per maggiori dettagli.

Suggerimenti per capirlo (suggerimento usando --dry-run)

Nel descrivere come fare, ho pensato di menzionare il --dry-runpassaggio a rsync. E 'estremamente utile nel vedere cosa accadrà senza che avvenga rsynceffettivamente.

Per esempio

L'uso del comando seguente eseguirà un test e ci mostrerà la logica decisionale alla base 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)

Nell'output sopra puoi vedere che le ./svndirectory sono protette dalla nostra regola di filtro. Informazioni preziose per il debug di rsync.

Riferimenti


Già provato questo, come ho detto sopra. Se lo faccio, viene inclusa anche la directory .SVN (molto probabilmente eliminata, perché non esiste nell'origine o modificata). È fondamentale lasciare intatta la directory .SVN. Grazie comunque per la prova! :)
Canolucas,

-C dovrebbe ignorare ". SVN /", ma lo include="*/"include
canolucas,

Hai ragione. Dovrebbe essere .svn, modificando la risposta. Comunque, dopo aver rinominato il problema rimane. -Ce include="*/"non sembrano essere amici intimi :(
canolucas,

10

Ok, dopo diversi tentativi ho risolto questo problema:

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

Grazie


Bella risposta. Il mio filtro protegge i .svn/dir --prune-empty-dirsnel caso siano vuoti. Un altro approccio, questo duplicando rsync -vaiz --delete --exclude=.svn/ --include='*.php' --include='*.js' --include='*/' --exclude='*' /origin /destination
dir

La chiave del mio approccio è quello di --exclude=.svn/prima del --include's
canolucas

Buona risposta pure Avrei suggerito un exclude = '. Svn /' ma pensavo che volessi usare il -C. Sono contento che tu l'abbia capito!
slm

0

Sebbene questo non stia usando rsync, un'altra opzione è quella di usare find e cpio. Ad esempio ho una directory chiamata Foto e che l'anno e il mese.

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

Ma qui ho jpg, dng, xml e altre cose e voglio solo i jpg, quindi farei questo

"cd" nella directory sopra la directory Photos quindi:

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

E il gioco è fatto

/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

Puoi usare questo metodo per molte cose, anni fa questo è il modo in cui copiare il filesystem / quando ci spostiamo su dischi più grandi come copierebbe i file del dispositivo.


Questo non risponde alla domanda.
RalfFriedl,

Lo fa se usa: find / origin -type f (-name " .php" -o -name " .js") -print | cpio -pdmvu / destination Solo i file * .php e * .js saranno nella directory di destinazione.
lxtwin il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.