Voici la partie importante de la page de manuel :
Au fur et à mesure que la liste des fichiers/répertoires à transférer est construite, rsync vérifie chaque nom à transférer par rapport à la liste des modèles d'inclusion/exclusion, et le premier modèle correspondant est utilisé :s'il s'agit d'un modèle d'exclusion, alors ce fichier est sauté ; s'il s'agit d'un motif d'inclusion, ce nom de fichier n'est pas ignoré ; si aucun modèle correspondant n'est trouvé, le nom de fichier n'est pas ignoré.
Pour résumer :
- Ne correspondant à aucun modèle signifie qu'un fichier sera copié !
- L'algorithme s'arrête une fois qu'un motif correspond
De plus, quelque chose se terminant par une barre oblique correspond à des répertoires (comme find -type d
le ferait).
Séparons cette réponse d'en haut.
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
- Ne sautez aucun répertoire
- Ne sautez aucun
.sh
fichiers - Ignorer tout
- (Implicitement, ne sautez rien, mais la règle ci-dessus empêche la règle par défaut de se produire.)
Enfin, le --prune-empty-directories
empêche la première règle de créer des répertoires vides partout.
Je pense --include
est utilisé pour inclure un sous-ensemble de fichiers qui sont autrement exclus par --exclude
, plutôt que d'inclure uniquement ces fichiers.En d'autres termes :vous devez penser à inclure ce qui signifie ne pas exclure .
Essayez plutôt :
rsync -zarv --include "*/" --exclude="*" --include="*.sh" "$from" "$to"
Pour rsync version 3.0.6 ou supérieure, l'ordre doit être modifié comme suit (voir commentaires) :
rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
Ajout du -m
flag évitera de créer des structures de répertoires vides dans la destination. Testé en version 3.1.2.
Donc, si nous ne voulons que des fichiers *.sh, nous devons exclure tous les fichiers --exclude="*"
, inclure tous les répertoires --include="*/"
et inclure tous les fichiers *.sh --include="*.sh"
.
Vous pouvez trouver quelques bons exemples dans la section Règles de modèle d'inclusion/exclusion de la page de manuel
Un ajout supplémentaire :si vous avez besoin de synchroniser des fichiers par leurs extensions dans un seul répertoire (sans récursivité) vous devez utiliser une construction comme celle-ci :
rsync -auzv --include './' --include '*.ext' --exclude '*' /source/dir/ /destination/dir/
Faites attention au point dans le premier --include
. --no-r
ne fonctionne pas dans cette construction.
MODIF :
Merci à gbyte.co pour le précieux commentaire !
MODIF :
Le -uzv
les drapeaux ne sont pas directement liés à cette question, mais je les ai inclus parce que je les utilise habituellement.
La réponse de @chepner copiera tous les sous-répertoires qu'ils contiennent ou non des fichiers. Si vous devez exclure les sous-répertoires qui ne contiennent pas le fichier tout en conservant la structure du répertoire, utilisez
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"