GNU/Linux >> Tutoriels Linux >  >> Linux

rsync utilisant regex pour n'inclure que certains fichiers

Je suggérerais d'utiliser l'option de filtrage de rsync. Pour votre exemple, tapez simplement :

rsync -vam -f'+ *[Nn][Aa][Mm][E]*' -f'+ */' -f'- *' a b

la première règle de filtrage indique à rsync les modèles à inclure. La deuxième règle est nécessaire pour indiquer à rsync d'inspecter tous les répertoires lors de sa traversée. Pour empêcher l'inclusion des répertoires vides, ils sont explicitement exclus par -m option. La dernière règle de filtrage indique à rsync de supprimer tous les modèles restants qui ne correspondent toujours pas jusqu'à présent.


rsync ne parle pas regex. Vous pouvez enrôler find et grep, bien que cela devienne un peu mystérieux. Pour trouver les fichiers cibles :

find a/ |
grep -i 'name'

Mais ils sont tous préfixés par "a/" - ce qui est logique, mais ce que nous voulons obtenir est une liste de modèles d'inclusion acceptables pour rsync, et comme le préfixe "a/" ne fonctionne pas pour rsync I' Je vais le supprimer en coupant :

find . |
grep -i 'name' |
cut -d / -f 2-

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 :

find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}'

Il ne reste plus qu'à envoyer la liste à rsync - nous pouvons utiliser l'argument --include-from=- pour fournir une liste de motifs à rsync sur l'entrée standard. Donc, tout à fait :

find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/

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 apporter une dernière modification et toujours faire référence au répertoire source par "./a/". Cependant, cela signifie que la commande de coupe doit changer car il y aura un "./" supplémentaire devant les résultats de find :

find ./a/ |
grep -i 'name' |
cut -d / -f 3- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/

Si vous utilisez ZSH, vous pouvez utiliser le drapeau (#i) pour désactiver la sensibilité à la casse. Exemple :

$ touch NAME
$ ls (#i)*name*
NAME

ZSH prend également en charge les exclusions, qui sont spécifiées comme le chemin normal, mais elles ont un ~

initial
$ touch aa ab ac
$ ls *~*c
aa ab

Vous pouvez enchaîner les exclusions :

$ ls *~*c~*b
aa

Enfin, vous pouvez spécifier le type de fichier que vous souhaitez renvoyer (répertoire, fichier, etc.). Cela se fait avec (/) pour répertoire et (.) pour fichier.

$ touch file
$ mkdir dir
$ ls *(.)
file

Sur la base de tout cela, je ferais cette commande comme :

rsync -avvz *(/) (#i)*name* ./a/ ./b/

(Je ne vois pas la nécessité d'une exclusion avec ces sélecteurs)


Linux
  1. Comment renommer un grand nombre de fichiers à l'aide d'une expression régulière ?

  2. Comment désactiver sélectivement Rsync ?

  3. Comment envoyer et télécharger des fichiers à l'aide de Rsync

  4. Sauvegardez vos fichiers avec rsync

  5. Utiliser rsync pour synchroniser les fichiers

Reprendre les fichiers partiellement transférés via SSH à l'aide de Rsync

Comment sauvegarder des fichiers et des répertoires à l'aide de Rsync sous Linux

Transférer des fichiers à l'aide de WinSCP

Comment copier des répertoires de manière récursive à l'aide de rsync tout en excluant des fichiers spécifiques

Utilisation des options d'inclusion et d'exclusion de Rsync pour inclure le répertoire et le fichier par modèle

rsync ne copie que certains types de fichiers à l'aide de l'option include