Rsync, n'inclut que certains types de fichiers à l'exception de certains répertoires

14

Je souhaite rsync uniquement certains types de fichiers (par exemple .py) et je veux exclure des fichiers dans certains répertoires (par exemple venv).

Voici ce que j'ai essayé:

rsync -avz --include='*/' --exclude='venv/' --include='*.py' --exclude='*' /tmp/src/ /tmp/dest/

Mais ça ne marche pas.

Qu'est-ce que je rate?

J'ai également suivi la réponse à cette question, mais cela n'a pas aidé.

CentAu
la source
pourquoi avez-vous besoin de l'initiale --include='*/'?
Charlie Parker
1
Comment créer la commande si j'ai des répertoires récursifs que je veux envoyer seulement un type de fichier. Il semble qu'il ne le fasse que pour le répertoire cible probablement à cause de la dernière exclusion qui exclut tout
Charlie Parker

Réponses:

17

venv/doit être exclu avant d' */ être inclus:

rsync -avz --exclude='venv/' --include='*/' --include='*.py' --exclude='*' /tmp/src/ /tmp/dest/

La subtilité est que rsyncles règles sont traitées dans l'ordre et la première règle correspondante gagne. Donc, si --include='*/'c'est avant --exclude='venv/', le répertoire venv/est inclus par --include='*/'et la règle d'exclusion n'est jamais consultée.

Pouvons-nous simplifier cela?

Pourquoi avons-nous besoin de --include='*/'et --exclude='*'? Pourquoi n'est-ce pas --exclude=venv/ --include='*.py'suffisant?

La valeur par défaut est d'inclure des fichiers / répertoires. Considérez donc:

rsync -avz --exclude='venv/' --include='*.py' source target

Cela comprendrait tout sauf les fichiers ou répertoires sous venv/. Cependant, vous ne voulez que des .pyfichiers. Cela signifie que nous devons explicitement exclure les autres fichiers avec --exclude='*'.

--exclude='*'exclut les fichiers et les répertoires. Donc, si nous spécifions --exclude='*', tous les répertoires seraient exclus et seuls les .pyfichiers dans le répertoire racine seraient trouvés. .pyles fichiers dans les sous-répertoires ne seraient jamais trouvés car rsyncne regardent pas dans les répertoires qui sont exclus. Ainsi, si nous l'avons --exclude='*', nous devons le précéder de --include='*/'pour nous assurer que le contenu de tous les répertoires est exploré.

John1024
la source
Génial! Merci! Juste pour ma compréhension, pourquoi avons-nous besoin de --include='*/'et --exclude='*'? Pourquoi seulement --exclude=venv/ --include='*.py'ne fonctionne pas?
CentAu
1
@CentAu Je viens de mettre à jour la réponse avec une discussion à ce sujet.
John1024
Comment créer la commande si j'ai des répertoires récursifs que je veux envoyer seulement un type de fichier. Il semble qu'il ne le fasse que pour le répertoire cible, probablement à cause de la dernière exclusion qui exclut tout.
Charlie Parker
1
Bookmarking! Surtout pour la subtilité. Je ne peux penser à aucun autre utilitaire CLI où l'ordre des drapeaux importe du tout!
antortjim