rsync bestimmte Dateien, mit Ausnahme der übrigen, rekursiv .svn / Verzeichnis zu ignorieren

19

Ich benutze, rsyncum einige Dateien von einer Freigabe auf eine andere zu kopieren.

Rekursiv muss ich:

  • Löschen Sie Dateien am Zielort, die vom Ursprung entfernt wurden
  • Nur synchronisieren .phpund .jsDateien
  • Schließen Sie alle anderen Dateitypen aus
  • Löschen Sie keine .svn/Verzeichnisse am Ziel

Wenn ich das benutze:

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

Dann rsyncist es nicht rekursiv, da exclude="*"alle Dateien, sondern auch Ordner ausgeschlossen werden.

Wenn ich hinzufüge, --include="*/"wird das .svn/Verzeichnis gelöscht (es wird auch eingeschlossen).

Wie kann ich dieses unglaubliche Dilemma lösen?

uname -a:

Linux tux 3.9.2-1-ARCH # 1 SMP PREEMPT Sa 11. Mai 20:31:08 MESZ 2013 x86_64 GNU / Linux

rsync Ausführung:

rsync 3.0.9-6
Canolucas
quelle

Antworten:

13

1. Versuch (hat nicht funktioniert)

Sie müssen die Verzeichnisse zusätzlich zu den Dateien einschließen:

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

2. Versuch

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

Testdaten

Ich habe dieses Skript geschrieben, um einige Beispieldaten zu erstellen und dies zu testen. Hier ist das Skript 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

Wenn Sie es ausführen, werden die folgenden Verzeichnisse erstellt:

Quelle 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

Ziel dir

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

Führen Sie den obigen rsyncBefehl aus:

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

Ergebnis 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

Warum funktioniert es?

Das Schlüsselelement dieses Skripts ist die Verwendung der Filterfunktion von rsync. Mit Filtern können Sie Dateien an verschiedenen Stellen des Befehls aus dem übereinstimmenden Satz entfernen. In unserem Fall filtern wir also alle Dateien, die dem Muster entsprechen */.svn*. Die Modifikatoren -rs_teilen dem Filter mit, dass sowohl auf der Quellseite als auch auf der Zielseite gefiltert werden soll.

Auszug aus dem Abschnitt FILTER NOTES auf der Manpage von rsync

  • Ein s gibt an, dass die Regel für die sendende Seite gilt. Wenn sich eine Regel auf die sendende Seite auswirkt, wird die Übertragung von Dateien verhindert. Standardmäßig wirkt sich eine Regel auf beide Seiten aus, sofern nichts --delete-excludedanderes angegeben wurde. In diesem Fall werden Standardregeln nur zur Absenderseite. Siehe auch die Regeln zum Ausblenden (H) und Anzeigen (S), die eine alternative Möglichkeit zum Angeben von senderseitigen Einschlüssen / Ausschlüssen darstellen.

  • Ein r gibt an, dass die Regel für die empfangende Seite gilt. Wenn sich eine Regel auf die empfangende Seite auswirkt, wird das Löschen von Dateien verhindert. Weitere Informationen finden Sie im Modifikator s. Siehe auch die Schutz- (P) und Risikoregeln (R), die eine alternative Möglichkeit darstellen, empfängerseitige Einschlüsse / Ausschlüsse festzulegen.

Weitere Informationen finden Sie unter man rsync .

Tipps, um dies herauszufinden (Hinweis mit --dry-run)

Während ich beschrieb, wie das geht, dachte ich, ich würde den --dry-runWechsel zu erwähnen rsync. Es ist äußerst nützlich zu sehen, was passieren wird, ohne dass das rsynctatsächlich stattfindet.

Beispielsweise

Mit dem folgenden Befehl führen Sie einen Testlauf durch und zeigen uns die Entscheidungslogik dahinter 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)

In der obigen Ausgabe können Sie sehen, dass die ./svnVerzeichnisse durch unsere Filterregel geschützt sind. Wertvoller Einblick für das Debuggen der rsync.

Verweise

slm
quelle
Habe das schon probiert, wie ich oben schon sagte. Wenn ich dies tue, wird auch das .SVN-Verzeichnis eingefügt (höchstwahrscheinlich gelöscht, da es im Ursprung nicht vorhanden ist oder geändert wurde). Es ist wichtig, dass das .SVN-Verzeichnis nicht verändert wird. Trotzdem danke für den Versuch! :)
Canolucas
-C soll ".SVN /" ignorieren, include="*/"schließt es aber ein
canolucas
Du hast recht. Es sollte sein .svn, die Antwort zu bearbeiten. Jedenfalls bleibt nach dem Umbenennen das Problem bestehen. -Cund include="*/"scheinen nicht sehr enge Freunde zu sein :(
Canolucas
10

Ok, nach mehreren Versuchen habe ich das sortiert:

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

Vielen Dank

Canolucas
quelle
Gute Antwort. Mein Filter schützt .svn/dirs vor, --prune-empty-dirsfalls sie leer sind. Ein weiterer Ansatz, der leere Verzeichnisse dupliziert:rsync -vaiz --delete --exclude=.svn/ --include='*.php' --include='*.js' --include='*/' --exclude='*' /origin /destination
canolucas
Der Schlüssel meiner Annäherung ist es, --exclude=.svn/vor dem --includes
canolucas
Gute Antwort auch. Ich hätte ein exclude = '. Svn /' vorgeschlagen, aber ich dachte, Sie wollten das verwenden -C. Schön, dass du es herausgefunden hast!
slm
0

Obwohl dies nicht rsync verwendet, können Sie auch find und cpio verwenden. Zum Beispiel habe ich ein Verzeichnis namens Fotos und das das Jahr und den Monat.

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

Aber hier habe ich jpg, dng, xml und andere Dinge und ich möchte nur die jpg's, also würde ich das tun

"cd" in das Verzeichnis über dem Photos-Verzeichnis, dann:

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

Und los geht's

/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

Sie können diese Methode für viele Dinge verwenden. Vor Jahren haben wir das Dateisystem / kopiert, wenn wir es auf größere Festplatten verschoben haben, so wie es Gerätedateien kopiert hat.

lxtwin
quelle
Das beantwortet die Frage nicht.
RalfFriedl
Es funktioniert, wenn er Folgendes verwendet: find / origin -type f (-name " .php" -o -name " .js") -print | cpio -pdmvu / destination Nur die Dateien * .php und * .js befinden sich im Zielverzeichnis.
Lxtwin