Suite d'outils en ligne de commande pour la manipulation et le traitement de fichiers vCard (contacts), permettant de nettoyer, séparer et ajouter des UUID aux cartes de visite virtuelles.
VCF Tools est une suite d'outils en ligne de commande que j'ai développée pour résoudre des problèmes courants de manipulation de fichiers vCard (contacts). Face à la difficulté de gérer de grands fichiers de contacts contenant plusieurs personnes, ou à la nécessité de nettoyer des cartes de visite superflues, j'ai créé ces outils pour automatiser ces tâches fastidieuses.
Ce projet démontre ma capacité à développer des solutions utilitaires efficaces en Bash, en m'appuyant sur des expressions régulières complexes et une gestion robuste des fichiers. Les outils sont conçus pour être légers, portables et sans dépendances externes, ce qui les rend faciles à installer et à utiliser sur différents systèmes.
Sépare un fichier vCard contenant plusieurs contacts en plusieurs fichiers vCard individuels. Chaque contact est extrait dans un fichier séparé nommé selon le nom du contact.
vcf-split contacts.vcf
# Crée: john_doe.vcf, jane_smith.vcf, etc.
Options : Mode verbose (-v) pour le débogage, gestion automatique des conflits de noms.
Supprime les champs indésirables des fichiers vCard comme les photos ou les lignes mal formatées. L'outil ne conserve que les lignes valides commençant par des champs vCard standards.
vcf-clean contact1.vcf contact2.vcf
# Nettoie les fichiers en place
Fonctionnement : Analyse ligne par ligne, filtre avec regex, préservation de la structure vCard valide.
Ajoute des identifiants uniques (UUID) à chaque vCard pour garantir une identification unique des contacts. Utile pour les systèmes qui nécessitent des identifiants uniques.
vcf-add-uuid *.vcf
# Ajoute un UUID à chaque contact dans tous les fichiers
Avantage : Évite les conflits d'identification lors de la synchronisation entre systèmes.
Voici un exemple concret de l'utilisation des outils VCF Tools pour traiter un fichier de contacts :
Cet exemple montre l'exécution de l'outil vcf-split pour séparer un fichier contenant plusieurs contacts en fichiers individuels, avec affichage des fichiers créés.
Défi : Le format vCard peut varier entre différents clients et applications, avec des différences de formatage, des encodages variables et des structures parfois malformées.
Solution : J'ai développé des expressions régulières robustes qui tolèrent les variations mineures du format tout en maintenant une validation stricte de la structure essentielle. L'approche consiste à valider ligne par ligne plutôt que de tenter de parser le fichier comme un tout.
# Regex pour identifier les lignes vCard valides
if [[ "$line" =~ ^[A-Z]+[:\;] ]]; then
# Ligne valide - traitement
fi
Défi : Lors de la séparation des contacts, plusieurs contacts peuvent avoir le même nom, ou certains contacts peuvent ne pas avoir de nom du tout, ce qui complique la génération de noms de fichiers uniques.
Solution : J'ai implémenté un algorithme de détection et de résolution de conflits qui génère automatiquement des noms de fallback uniques en utilisant des timestamps et des numéros de séquence.
# Gestion des conflits de noms
if [[ -z "$card_name" ]] || [[ -f "$card_name" ]]; then
card_name="$(date --rfc-3339 date)_card${card_number}"
fi
Défi : Les fichiers vCard peuvent contenir des milliers de contacts et devenir très volumineux. Charger tout le fichier en mémoire pourrait être inefficace ou impossible sur des systèmes avec des ressources limitées.
Solution : J'ai adopté une approche de traitement ligne par ligne qui ne charge qu'une petite partie du fichier en mémoire à un moment donné. Cela permet de traiter des fichiers arbitrairement grands sans problème de mémoire.
# Traitement ligne par ligne
while IFS= read -r line; do
# Traitement de chaque ligne individuellement
if [[ "$line" =~ ^END:VCARD ]]; then
# Fin d'une carte - écriture du fichier
printf "%s\n" "${card_lines[@]}" > "$file"
card_lines=()
fi
done < "$file"
Défi : Les outils doivent être robustes face aux erreurs (fichiers inexistants, permissions incorrectes, formats invalides) tout en fournissant des messages d'erreur clairs à l'utilisateur.
Solution : J'ai implémenté une validation complète des entrées avec des messages d'erreur explicites et une gestion gracieuse des erreurs. Chaque outil vérifie l'existence des fichiers, les permissions, et valide le format avant traitement.
# Validation des entrées
if [ ! -f "$file" ]; then
echo "File '$file' not found!"
continue
fi
Cet extrait montre le cœur de l'algorithme de vcf-split qui détecte la fin d'une carte et écrit le fichier correspondant :
# Detection de la fin d'une carte vCard
if [[ "$line" =~ ^END:VCARD ]]; then
# Generation du nom de fichier
if [[ -z "$card_name" ]] || [[ -f "$card_name" ]]; then
card_name="$(date --rfc-3339 date)_card${card_number}"
fi
# Ecriture du fichier de contact
printf "%s\n" "${card_lines[@]}" > \
"$(echo -n "$card_name" | \
tr "[:upper:]" "[:lower:]" | \
tr -dc "[:alnum:]\n " | \
tr " " "_").vcf"
# Reinitialisation pour le prochain contact
unset -v card_lines
unset -v card_name
let "card_number=card_number+1"
fi
Points clés : Détection robuste des fins de carte, gestion des conflits de noms, normalisation des noms de fichiers, réinitialisation propre des variables.
Cet extrait de vcf-clean montre comment les lignes sont filtrées pour ne conserver que les champs vCard valides :
# Filtrage des lignes vCard valides
while IFS= read -r line; do
# Ignore les lignes qui ne commencent pas
# par un champ vCard valide (A-Z suivi de : ou ;)
if ! [[ "$line" =~ ^[A-Z]+[:\;] ]]; then
continue
fi
# Ajoute la ligne valide au tableau
card_lines+=("$line")
# Detection de la fin de la carte
if [[ "$line" =~ ^END:VCARD ]]; then
printf "%s\n" "${card_lines[@]}" > "$file"
card_lines=()
fi
done < "$file"
Points clés : Regex précise pour la validation, filtrage efficace des lignes indésirables, préservation de la structure vCard, traitement en streaming.