J'essaie d'exécuter rsync pour copier certains fichiers récursivement sur un chemin basé sur leur modèle de nom de fichier, sans tenir compte de la casse . Voici ce que j'ai fait pour exécuter rsync:
$ rsync -avvz --include ='*/' --include='.*[Nn][Aa][Mm][E].*' --exclude='*' ./a/ ./b/
Rien n'est copié, la sortie de débogage montre:
[sender] hiding file 1Name.txt because of pattern *
[sender] hiding file 1.txt because of pattern *
[sender] hiding file 2.txt because of pattern *
[sender] hiding file Name1.txt because of pattern *
[sender] hiding directory test1 because of pattern *
[sender] hiding file NaMe.txt because of pattern *
J'ai essayé d'utiliser: --include='*[Nn][Aa][Mm][E]*'
et d'autres combinaisons mais ça ne marche toujours pas.
Des idées sur la façon d'utiliser regex pour inclure certains fichiers?
--exclude='*'
?Réponses:
rsync ne parle pas regex. Vous pouvez enrôler find et grep, bien que cela devienne un peu mystérieux. Pour rechercher les fichiers cibles:
Mais ils sont tous préfixés par "a /" - ce qui est logique, mais ce que nous voulons nous retrouver c'est une liste de modèles d'inclusion acceptables pour rsync, et comme le préfixe "a /" ne fonctionne pas pour rsync I ' ll le retirer avec coupe:
Il y a toujours un problème - nous manquerons toujours des fichiers dans les sous-répertoires, car rsync ne recherche pas les répertoires dans la liste d'exclusion. Je vais utiliser awk pour ajouter les sous-répertoires de tous les fichiers correspondants à la liste des modèles d'inclusion:
Il ne reste plus qu'à envoyer la liste à rsync - nous pouvons utiliser l'argument --include-from = - pour fournir une liste de modèles à rsync sur une entrée standard. Donc, tout à fait:
Notez que le répertoire source 'a' est référencé via deux chemins différents - "a /" et "./a/". C'est subtil mais important. Pour rendre les choses plus cohérentes, je vais faire un dernier changement, et toujours faire référence au répertoire source comme "./a/". Cependant, cela signifie que la commande cut doit changer car il y aura un "./" supplémentaire sur le devant des résultats de find:
la source
-t
c'est un interrupteur valide.sed "s#^$1/*##"
buuuut qui se cassera sur les chemins qui contiennent un #. Pour résoudre ce problème, nous devons citer le nom du répertoire entrant:prefix=$(echo "$1" | sed 's#/#\\/#g')
puissed "s/^$prefix\\/*//"
les sous-qualités de la citation bash sont un peu un cauchemar;)Je suggérerais d'utiliser l'option de filtre de rsync. Pour votre exemple, tapez simplement:
la première règle de filtrage indique à rsync les modèles à inclure. La deuxième règle est nécessaire pour dire à rsync d'inspecter tous les répertoires sur sa traversée. Pour empêcher l'inclusion de répertoires vides, ils sont exclus explicitement par
-m
option. La dernière règle de filtrage indique à rsync de supprimer tous les modèles restants qui ne correspondaient pas jusqu'à présent.la source
Si vous utilisez ZSH, vous pouvez utiliser l'indicateur (#i) pour désactiver la sensibilité à la casse. Exemple:
ZSH prend également en charge les exclusions, qui sont spécifiées tout comme le chemin d'accès normal, mais elles ont un ~ initial
Vous pouvez chaîner des exclusions:
Enfin, vous pouvez spécifier le type de fichier que vous souhaitez renvoyer (répertoire, fichier, etc.). Cela se fait avec (/) pour le répertoire et (.) Pour le fichier.
Sur la base de tout cela, je ferais cette commande comme:
(Je ne vois pas la nécessité d'une exclusion avec ces sélecteurs)
la source
La réponse de @ sqweek ci-dessus est impressionnante, même si je soupçonne qu'il a un bug dans son
awk
script pour générer des répertoires parents, car cela me donne par exemple:J'ai pu le réparer en utilisant à la
gensub
place:Donc, sa solution complète, avec le
awk
bit changé, serait:la source
sub("/[^/]*$")
).J'ai essayé avec un script C # car c'est le langage avec lequel j'ai le plus d'expérience. Je peux créer la liste des fichiers que je veux inclure, mais quelqu'un rsync me dit toujours de faire une randonnée. Il crée les dossiers, mais il ignore les fichiers. Voici ce que j'ai obtenu ..
D'abord le contenu du répertoire:
Ensuite, la sortie du script C #:
Et la sortie de débogage:
la source
[EDIT] Cela ne fonctionne que localement. Pour les chemins distants, la structure de répertoires doit d'abord être créée.
Plus simple que la réponse acceptée; Utilisez --file-from, qui inclut automatiquement les répertoires parents et affichez le chemin du fichier avec% P
Vous n'avez donc qu'à utiliser
find
etrsync
.la source