web-dev-qa-db-fra.com

Comment utiliser Rsync pour copier uniquement des sous-répertoires spécifiques (mêmes noms dans plusieurs répertoires)

J'ai une telle structure de répertoires sur le serveur 1:

  • les données
    • company1
      • dossier_unique1
      • autre dossier
      • ...
    • company2
      • dossier_unique1
      • ...
    • ...

Et je veux dupliquer cette structure de dossiers sur le serveur 2, mais copier uniquement les répertoires/sous-répertoires de unique_folder1. C'est à dire. comme résultat doit être:

  • les données
    • company1
      • dossier_unique1
    • company2
      • dossier_unique1
    • ...

Je sais que rsync est très bon pour cela. J'ai essayé les options "inclure/exclure" sans succès.

Par exemple. J'ai essayé:

rsync -avzn --list-only --include '*/unique_folder1/**' --exclude '*' -e ssh [email protected]:/path/to/old/data/ /path/to/new/data/

Mais, en conséquence, je ne vois aucun fichier/répertoire:

receiving file list ... done
sent 43 bytes  received 21 bytes  42.67 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

Qu'est-ce qui ne va pas? Des idées?


Informations supplémentaires: J'ai accès à Sudo aux deux serveurs. Une idée que j'ai - est d'utiliser la commande find et cpio ensemble pour copier dans un nouveau répertoire avec le contenu dont j'ai besoin et ensuite utiliser Rsync. Mais c'est très lent, il y a beaucoup de fichiers, etc.

30
Andron

J'ai trouvé la raison. Quant à moi, il n'était pas clair que Rsync fonctionne de cette façon.
Commande donc correcte (pour company1 répertoire uniquement) doit être:

rsync -avzn --list-only --include 'company1/' --include 'company1/unique_folder1/***' --exclude '*' -e ssh [email protected]:/path/to/old/data/ /path/to/new/data

C'est à dire. nous devons inclure chaque répertoire parent company. Et bien sûr, nous ne pouvons pas écrire manuellement tous ces répertoires company dans la ligne de commande, nous enregistrons donc la liste dans le fichier et nous l'utilisons.


Dernières choses que nous devons faire:

1.Générez le fichier d'inclusion sur le serveur 1, donc son contenu sera (j'ai utilisé ls et awk):

+ company1/  
+ company1/unique_folder1/***  
...  
+ companyN/  
+ companyN/unique_folder1/***  

2.Copiez include.txt sur le serveur 2 et utilisez une telle commande:

rsync -avzn                                        \
      --list-only                                  \
      --include-from '/path/to/new/include.txt'    \
      --exclude '*'                                \
      -e ssh [email protected]:/path/to/old/data/    \
      /path/to/new/data
28
Andron

Si le premier modèle correspondant exclut un répertoire, tous ses descendants ne seront jamais parcourus. Lorsque vous souhaitez inclure un répertoire complet, par exemple company*/unique_folder1/** mais exclure tout le reste *, vous devez indiquer à rsync d'inclure également tous ses ancêtres:

rsync -r -v --dry-run                       \
    --include='/'                           \
    --include='/company*/'                  \
    --include='/company*/unique_folder1/'   \
    --include='/company*/unique_folder1/**' \
    --exclude='*'

Vous pouvez utiliser l'expansion d'accolade de bash pour enregistrer une saisie. Après l'expansion de l'accolade, la commande suivante est exactement la même que la précédente:

rsync -r -v --dry-run --include=/{,'company*/'{,unique_folder1/{,'**'}}} --exclude='*'
16
yonran

Par exemple, si vous souhaitez uniquement synchroniser target/classes/ et target/lib/ à un système distant, faites

rsync -vaH --delete --delete-excluded --include='classes/***' --include='lib/***' \
      --exclude='*' target/ user@Host:/deploy/path/

Les choses importantes à surveiller:

  • N'oubliez pas le "/ "à la fin des chemins, ou vous obtiendrez une copie dans le sous-répertoire.
  • L'ordre du --include, --exclude compte.
  • Contrairement aux autres réponses, en commençant par "/ "un paramètre d'inclusion/exclusion n'est pas nécessaire, il sera automatiquement ajouté au répertoire source (target/ dans l'exemple).
  • Pour tester ce qui se passera exactement, nous pouvons utiliser un --dry-run drapeaux, comme le disent les autres réponses.
  • --delete-excludedsupprimera tout le contenu du répertoire cible, à l'exception des sous-répertoires que nous avons spécifiquement inclus. Il doit être utilisé à bon escient! Pour cette raison, un --delete ne suffit pas, il ne supprime pas les fichiers exclus du côté distant par défaut (tous les autres, oui), il doit être donné à côté de l'ordinaire --delete, encore.
1
peterh