J'essaie de créer un répertoire qui contiendra tous et uniquement mes PDF compilés à partir de LaTeX. J'aime garder chaque projet dans un dossier séparé, le tout logé dans un grand dossier appelé LaTeX
. Alors j'ai essayé de courir:
rsync -avn *.pdf ~/LaTeX/ ~/Output/
qui devrait trouver tous les fichiers PDF ~/LaTeX/
et les transférer dans le dossier de sortie. Ça ne marche pas. Il me dit qu'il n'a trouvé aucune correspondance pour " *.pdf
". Si je laisse ce filtre de côté, la commande répertorie tous les fichiers de tous les dossiers du projet sous LaTeX. C'est donc un problème avec le filtre * .pdf. J'ai essayé de remplacer ~/
par le chemin complet de mon répertoire personnel, mais cela n'a pas eu d'effet.
Je suis en utilisant zsh. J'ai essayé de faire la même chose en bash et même avec le filtre qui répertorie chaque fichier dans chaque sous-répertoire ... Qu'est-ce qui se passe ici?
Pourquoi rsync ne comprend-il pas mon filtre PDF uniquement?
D'ACCORD. Donc mise à jour: Non j'essaie
rsync -avn --include="*/" --include="*.pdf" LaTeX/ Output/
Et cela me donne la liste complète des fichiers. Je suppose que tout correspond au premier motif ...
**
motif de zsh ) devrait marcher, cependant.Réponses:
TL, DR:
Rsync copie la ou les sources vers la destination. Si vous passez en
*.pdf
tant que sources, le shell étend cette liste à la liste des fichiers portant l'.pdf
extension dans le répertoire en cours. Aucune traversée récursive ne se produit car vous n'avez passé aucun répertoire en tant que source.Vous devez donc exécuter
rsync -a ~/LaTeX/ ~/Output/
, mais avec un filtre, indiquer à rsync de ne copier.pdf
que les fichiers. Les règles de filtrage de Rsync peuvent sembler décourageantes lorsque vous lisez le manuel, mais vous pouvez construire de nombreux exemples avec quelques règles simples.Inclusions et exclusions:
--exclude=*~
,--exclude=/some/relative/location
( par rapport à l'argument source, par exemple ceci exclut~/LaTeX/some/relative/location
).--include=*/
), puis excluez le reste avec--exclude='*'
. Ceci est dû au fait:--include='directory/***'
nous le ferons.Les motifs:
/
, il s'applique au nom de fichier sans répertoire./
, il s’applique uniquement aux répertoires./
, il s'applique à tout le chemin du répertoire passé en argumentrsync
.*
toute sous-chaîne d'un seul composant de répertoire (c'est-à-dire qu'elle ne correspond jamais/
);**
correspond à n'importe quelle sous-chaîne de chemin.Si un argument source se termine par un
/
, son contenu est copié (rsync -r a/ b
créeb/foo
pour chaquea/foo
). Sinon, le répertoire lui-même est copié (rsync -r a b
créeb/a
).Nous devons donc inclure
*.pdf
, inclure les répertoires les contenant et exclure tout le reste.Notez que cela copie tous les répertoires, même ceux qui ne contiennent aucun fichier ou sous-répertoire correspondant. Cela peut être évité avec l'
--prune-empty-dirs
option (ce n'est pas une solution universelle car vous ne pouvez pas copier un répertoire même en le faisant correspondre explicitement, mais c'est une exigence rare).la source
**
modèle de zsh ), cela recrée la structure de répertoires dans le répertoire cible. Je ne sais pas si c'est ce que le PO veut .../etc/lsyncd/lsyncd.conf.lua
fichier. Avez-vous une idée?La valeur par défaut consiste à tout inclure. Vous devez donc explicitement tout exclure après avoir inclus les fichiers que vous souhaitez transférer. Supprimez le --dry-run pour transférer les fichiers.
Si vous commencez avec:
Ensuite, la correspondance gourmande exclura tout de suite.
Si tu essayes:
Ensuite, seuls les fichiers pdf du dossier de niveau supérieur seront transférés. Il ne suivra aucun répertoire, car ceux-ci sont exclus par '*'.
la source
--prune-empty-dirs
(ou raccourci-m
), vous vous épargnez même de nombreux répertoires vides sur la destination, sauf bien sûr, vous les souhaitez comme rappel ou modèle de structure./etc/lsyncd/lsyncd.conf.lua
fichier. Avez-vous une idée?Si vous utilisez un modèle tel que
*.pdf
, le shell "développe" ce modèle, c'est-à-dire qu'il remplace le modèle par toutes les correspondances du répertoire en cours. La commande que vous exécutez (dans ce cas, rsync) ignore que vous avez essayé d'utiliser un modèle.Lorsque vous utilisez zsh , il existe une solution simple: Le
**
modèle peut être utilisé pour faire correspondre les dossiers de manière récursive. Essaye ça:la source
rsync -avn ~/LaTeX/**/*.pdf ~/Output
, mais la solution avec--include
est plus évolutive de toute façon.**
pourrait également s'avérer utile dans d'autres situations.cd ~/Latex && cp -p **/*.pdf ~/Output
d’éviter une erreur «ligne de commande trop longue».Vous pouvez utiliser
find
une liste intermédiaire de fichiers (files_to_copy
) pour résoudre votre problème. Assurez-vous que vous êtes dans votre répertoire personnel, puis:find LaTeX/ -type f -a -iname "*.pdf" > files_to_copy && rsync -avn --files-from=files_to_copy ~/ ~/Output/ && rm files_to_copy
Testé avec Bash.
la source
-exec
option trouvailles ou l’utilisation dexargs
. Quelque chose comme:find LaTeX/ -type f -iname "*.pdf" -print0 | xargs -0 -i rsync -avn {} Output/
standalone
ou qui n’ont pas de.tex
fichier du même nom, car ce sont des images incluses dans certains documents ...--files-from
accepte la lecture de stdin. Cela fonctionneraitfind LaTeX/ -type f -a -iname "*.pdf" | rsync -avn --files-from=- ~/ ~/Output/
A en juger par la section "INCLUDE / EXCLUDE PATTERN RULES" de la page de manuel , la manière de procéder est la suivante:
La différence critique entre ceci et la réponse de kbrd est le
--include="*/"
drapeau, qui indique à rsync de continuer et de copier tous les répertoires trouvés, quel que soit leur nom. Cela est nécessaire car rsync ne recurse pas dans un sous-répertoire à moins d’avoir été invité à copier ce sous-répertoire.Notez également que les guillemets empêchent le shell d'essayer de développer les modèles en noms de fichiers relatifs au répertoire en cours et d'effectuer l'une des opérations suivantes:
Réussir et gâcher votre filtre (pas très probablement au milieu d'un drapeau comme celui-ci, bien que vous ne sachiez jamais quand quelqu'un créera un fichier nommé
--include=foo.pdf
...)Échec et éventuellement production d’une erreur au lieu d’exécuter la commande (comme vous avez découvert zsh le fait par défaut).
la source
include
ajouter des éléments supplémentaires ne change rien. Si vous voyez ce que je veux dire ...--exclude="*"
après le--include="*.pdf"
, ou cela transférera tout.Que dis-tu de ça:
la source
man rsync
place le filtre après les options et avant la source / destination. J'ai essayé cela et cela n'a pas fonctionnéa
option est pour l'archive et entre autres choses, elle rend la copie récursive.Voici quelque chose qui devrait fonctionner sans utiliser find. La différence par rapport aux réponses déjà postées correspond à l'ordre des règles de filtrage. Les règles de filtrage dans une commande rsync fonctionnent beaucoup comme les règles iptables, la première règle à laquelle un fichier correspond est celle utilisée. De la page de manuel :
Ainsi, vous avez besoin d'une commande comme suit:
Notez le motif "**. Pdf". Selon la page de manuel :
Dans mon petit test, cela fonctionne de manière récursive dans l'arborescence de répertoires et ne sélectionne que les fichiers PDF.
la source
*.pdf
copiée que dans le répertoire toplevel (mais pas~/LaTeX/foo/bar.pdf
).**
. Ce serait bien d'en avoir un exemple. ;)Ceci est ma solution préférée:
La
find
commande est plus facile à comprendre que les règles d'inclusion / exclusion dersync
:-)Si vous souhaitez copier uniquement des fichiers pdf, il suffit de changer
.jpg
à.pdf
la source