#!/usr/bin/python
# -*- coding: utf-8 -*-
# si python < 3
from __future__ import print_function
usage = """
[usage] %s --table1 <fichier tableau CSV1> --table2 <fichier tableau CSV2> --jointable <fichier jointure tableau CSV> --sep <séparateur de champs> --format <format affichage des données à afficher avec %s pour chaque colonne à afficher> --colonnes <couples numéro de fichier (1 ou 2) «.» numéros de colonnes pour chaque %s du format donné précédemment ; séparés par des «,»>
Ce script a pour but de faire une jointure entre 3 fichiers :
- Un permier contenant une liste (genre CSV) séparée par un séparateur
(par défaut «|») avec plusieurs champs dont le premier est
l'identifiant unique (ou alors un autre numéro de colonne considérée
comme contenant l'identifiant).
- Un deuxième contenant une liste (genre CSV) séparée par un
séparateur (par défaut «|») avec plusieurs autres champs et entrées
dont le premier (par défaut) est l'identifiant unique. On peut
également donner un numéro de colonne pour cet identifiant.
- un troisième fichier contenant au moins deux colonnes avec, dans le
premier champ (séparateur = «|»), une liste d'identifiants
correspondants au premier fichier (on peut aussi donner un numéro de
colonne si ce n'est pas la première — valeur par défaut).et le
deuxième champ correspondant à l'identifiant du deuxième fichier (avec
un séparateur = «|» par défaut) et un numéro de colonne = 2 par défaut
mais qui peut être précisé.
Les numéros de colonnes commencent à 1.
"""
import sys
import os
from optparse import OptionParser
# traitement des options
parser = OptionParser(usage)
parser.add_option("--table1", dest="ftable1",
help="Tableau CSV 1")
parser.add_option("--colonne_id1", dest="ct1", default=1, type="int",
help="Numero de colonne de l'identifiant du premier tableau CSV")
parser.add_option("--table2", dest="ftable2",
help="Tableau CSV 2")
parser.add_option("--colonne_id2", dest="ct2", default=1, type="int",
help="Numero de colonne de l'identifiant du deuxieme tableau CSV")
parser.add_option("--jointable", dest="fjointable",
help="Tableau CSV contenant les identifiants uniques des 2 tableaux CSV 1 et 2")
parser.add_option("--colonne_jid1", dest="cj1", default=1, type="int",
help="Numero de colonne de l'identifiant du premier tableau CSV dans le fichier de jointure (le troisieme fichier)")
parser.add_option("--colonne_jid2", dest="cj2", default=2, type="int",
help="Numero de colonne de l'identifiant du deuxieme tableau CSV dans le fichier de jointure (le troisieme fichier)")
parser.add_option("--sep", dest="sep", default="|",
help="Separateur utilise pour tous les fichiers-tableaux CSV - un seul caractere attendu - valeur par defaut le pipe")
#parser.add_option("--sep1", dest="sep1",
# help="Separateur utilise pour le fichiers-tableaux CSV 1 - un seul caractere attendu - pas de valeur par defaut")
#parser.add_option("--sep2", dest="sep2",
# help="Separateur utilise pour le fichiers-tableaux CSV 2 - un seul caractere attendu - pas de valeur par defaut")
#parser.add_option("--sepj12", dest="sepj12",
# help="Separateur utilise pour le fichiers-tableaux CSV de jointure - un seul caractere attendu - pas de valeur par defaut")
parser.add_option("--format", dest="format",
help="Format avec des %s le ou seront les donnees reprises des colonnes des deux tableaux CSV")
parser.add_option("--colonnes", dest="colonnes",
help="Couples numero de fichier (1 ou 2) '.' numeros de colonnes pour chaque %s du format donne precedemment; separes par des ','")
(options, args) = parser.parse_args()
#if len(args) <= 6:
# parser.error("Incorrect number of arguments")
# parser.error(usage % sys.argv[0])
# sys.exit(2)
t1 = {} # tableau de hashage contenant les enregistrements du premier fichier-tableau avec la colonne identifiant unique comme clé
t2 = {} # tableau de hashage contenant les enregistrements du deuxième fichier-tableau avec la colonne identifiant unique comme clé
sep = options.sep # le séparateur utilisé
ct1 = options.ct1 - 1 # le numéro de colonne contenant l'identifiant unique du premier tableau du premier fichier
ct2 = options.ct2 - 1 # le numéro de colonne contenant l'identifiant unique du second tableau du deuxième fichier
cj1 = options.cj1 - 1 # le numéro de colonne contenant l'identifiant unique du premier tableau dans le troisième fichier, fichier de jonction entre les deux premiers
cj2 = options.cj2 - 1 # le numéro de colonne contenant l'identifiant unique du second tableau dans le troisième fichier, fichier de jonction entre les deux premiers
with open(options.ftable1, 'r') as table1:
for ligne in table1:
ligne = ligne.rstrip()
tl1 = ligne.split(sep)
if len(tl1) <= ct1:
print("[Erreur] Le numéro de colonne de l'identifiant du tableau CSV 1 dépasse le nombre de colonne de la ligne: %d pour %d max colonnes" % (ct1, len(tl1)), file=sys.stderr)
continue
id1 = tl1[ct1]
t1[id1] = tl1
with open(options.ftable2, 'r') as table2:
for ligne in table2:
ligne = ligne.rstrip()
tl2 = ligne.split(sep)
if len(tl2) <= ct2:
print("[Erreur] Le numéro de colonne de l'identifiant du tableau CSV 2 dépasse le nombre de colonne de la ligne: %d pour %d max colonnes" % (ct2, len(tl2)), file=sys.stderr)
continue
id2 = tl2[ct2]
t2[id2] = tl2
with open(options.fjointable, 'r') as jointure_t12:
for ligne in jointure_t12:
ligne = ligne.rstrip()
jt12 = ligne.split(sep)
if len(jt12) <= cj1 or len(jt12) <= cj2:
print("[Erreur] Le numéro de colonne de l'identifiant du tableau de jointure dépasse le nombre de colonne de la ligne: %d (identifiant tableau1) - %d (identifiant tableau2) - pour %d max colonnes" % (cj1, cj2, len(jt12)), file=sys.stderr)
continue
jid1 = jt12[cj1]
jid2 = jt12[cj2]
try:
tableau_a_afficher = []
for i in options.colonnes.split(","):
(filenumber, colnumber) = i.split(".")
if int(filenumber) == 1:
# on enlève 1 au numéro de colonne car ce numéro commence à 1 contrairement aux tableaux python
tableau_a_afficher.append(t1[jid1][int(colnumber) - 1])
elif int(filenumber) == 2:
tableau_a_afficher.append(t2[jid2][int(colnumber) - 1])
# pour que le format d'affichage (tableau_a_afficher) soit interprété correctement par print,
# il faut que ce soit un tuble et nom un tableau.
print(options.format % tuple(tableau_a_afficher))
except KeyError as k:
print("Erreur de clé pour jid1 %s- jid2 %s" % (jid1, jid2), file=sys.stderr)
continue
|