Synchronsier plusieurs fichiers avec awk

Fermé
Super_Didji Messages postés 4 Date d'inscription vendredi 12 février 2010 Statut Membre Dernière intervention 15 février 2010 - 12 févr. 2010 à 23:14
Super_Didji Messages postés 4 Date d'inscription vendredi 12 février 2010 Statut Membre Dernière intervention 15 février 2010 - 15 févr. 2010 à 00:10
Bonjour,

Voici mon problème

exposé :
========

j'ai un fichier1 (fichier clients) qui contient 5 champs (fichier csv) :
- champ1 est le numéro de client
- champ2 est le nom du client
- champ3 est l'adresse du client
- champ4 est la ville du client
- champ5 est le département du client

soit par exemple :
1	dupont	11 rue des jasmins	oiseville 	60
2	dubois	12 rue des oeillets	laville s mer	76
3 	durand	13 rue des roses	nordville	59
4	dugnou	14 rue des lilas  	sudville	34


ce fichier est trié par numéro de client (champ1)

j'ai un fichier2 (fichiers des liens clients/contrats) qui contient 5 champs (fichier csv) :
- champ1 est le numéro de client
- champ2 est le numéro de contrat
- champ3 est le type de contrat
- champ4 est le role du client dans le contrat
- champ5 est le département du client

soit par exemple :
1	1	0	titulaire	?
1	2	1	bénéficiaire	?
2	2	0 	bénéficiaire	?
3 	3	0	titulaire	?
3 	4	1	titulaire	?
3 	5	2	titulaire	?


ce fichier est trié par numéro de client
on voit que le champ5 est mal alimenté (?) ; il y a n'importe quoi dedans.

L'objet de l'exercice est de l'alimenter correctement

donc à partir des fichier1 et fichier2 construire un fichier3 qui serait le fichier2 corrigé :

dans l'exemple :

1	1	0	titulaire	60
1	2	1	bénéficiaire	60
2	2	0 	bénéficiaire	76
3 	3	0	titulaire	59
3 	4	1	titulaire	59
3 	5	2	titulaire	59

Algorithme

==========

FF1:=0		init flag fin fichier1
FF2:=0		init flag fin fichier2
FL1:=1		init flag lecture fichier 1
FL2:=1	        init flag lecture fichier 2
Tant que FF2 <> 0 alors
	Si FL2=1 et FF2=0 alors
		lire_ligne  fichier2
		Si Fin de fichier2 alors
			FF2:=1
		Sinon
			Var2:=fichier2.champ1
		Fsi
	Fsi
	Si FL1=1 et FF1=0 alors
		lire_ligne fichier1
		Si Fin de fichier1 alors
			FF1:=1
		Sinon
			Var1:=fichier1.champ1
		Fsi
	Fsi	
	Si Var1=Var2 alors
		Fichier2.champ5:=Var1
		ligne_Fichier3:=ligne_Fichier2		
		Ecrire_ligne Fichier3
		FL1:=0
		FL2:=1
	Sinon
		FL1:=1
		FL2:=0
	Fsi
FinTantque


quelques compléments :
======================
les fichiers en question dans la réalité ont quelques dizaines de colonnes (moins de 50) mais de 2à à 50 millions de lignes.

J'ai donc penser à AWK.

Je connais un peu mais pas suffisamment.

Quelqu'un peut-il m'aider, car pour un AWKman confirmé, ça doit être de la rigolade.

A votre disposition si besoin d'explications.
A voir également:

14 réponses

lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
13 févr. 2010 à 07:58
Salut,

$ cat base_clients.csv 
1       dupont  11 rue des jasmins      oiseville       60
2       dubois  12 rue des oeillets     laville s mer   76
3       durand  13 rue des roses        nordville       59
4       dugnou  14 rue des lilas        sudville        34
$ cat base_contrats.csv 
1       1       0       titulaire       ?
1       2       1       bénéficiaire    ?
2       2       0       bénéficiaire    ?
3       3       0       titulaire       ?
3       4       1       titulaire       ?
3       5       2       titulaire       ?
$ awk -F"\t" 'BEGIN{OFS="\t"}{if(!x[$1]) {x[$1]=$5} else {$5=x[$1];print}}' base_clients.csv base_contrats.csv 
1       1       0       titulaire       60
1       2       1       bénéficiaire    60
2       2       0       bénéficiaire    76
3       3       0       titulaire       59
3       4       1       titulaire       59
3       5       2       titulaire       59


1
Bonjour,

tout d'abord mercu pour la réponse :

J'ai essayé :

didier@didier-desktop:~$ cat base_clients.csv
1	dupont	11 rue des jasmins      oiseville       60
2       dubois  12 rue des oeillets     laville s mer   76
3       durand  13 rue des roses        nordville       59
4       dugnou  14 rue des lilas        sudville        34

didier@didier-desktop:~$ cat base_contrats.csv
1       1       0       titulaire       ?
1       2       1       bénéficiaire    ?
2       2       0       bénéficiaire    ?
3       3       0       titulaire       ?
3       4       1       titulaire       ?
3       5       2       titulaire       ?

et puis :
didier@didier-desktop:~$ awk -F"\t" 'BEGIN{OFS="\t"}{if(!x[$1]){x[$1]=$5}else{$5=x[$1];print}}' base_clients.csv base_contrats.csv
didier@didier-desktop:~$

tout va bien, mais le résultat ?
et là j('ai cerché :
didier@didier-desktop:~$ ls -rtl
total 98048
...
...
-rw-r--r--  1 didier didier      552 2010-02-12 15:33 synchro_fichiers.txt~
-rw-r--r--  1 didier didier     2337 2010-02-12 15:57 synchro_fichiers.txt
-rw-r--r--  1 didier didier      229 2010-02-14 12:51 base_clients.csv
-rw-r--r--  1 didier didier      256 2010-02-14 12:52 base_contrats.csv

didier@didier-desktop:~$ cat bas*.csv

1	dupont	11 rue des jasmins      oiseville       60
2       dubois  12 rue des oeillets     laville s mer   76
3       durand  13 rue des roses        nordville       59
4       dugnou  14 rue des lilas        sudville        34
1       1       0       titulaire       ?
1       2       1       bénéficiaire    ?
2       2       0       bénéficiaire    ?
3       3       0       titulaire       ?
3       4       1       titulaire       ?
3       5       2       titulaire       ?

didier@didier-desktop:~$
didier@didier-desktop:~$

je ne comprends pas et ne vois pas pù est le résultat attendu.

Si tu peux m'expliquer le blème ...

merci d'avance

Super_Didji
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 897
14 févr. 2010 à 13:30
Salut,

Aucun affichage sur la console lors de l'exécution de la commande ?

Affiche le résultat de :

cat -A bas*.csv
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
14 févr. 2010 à 14:13
Salut,

Si tu peux m'expliquer le blème ...
Ben, le blème est qu'on a besoin de tes fichiers pour tester.

Aucun affichage sur la console lors de l'exécution de la commande ?
On arrive toujours à cette situation quand on teste sur les exemples de fichiers qu'on crée nous même au lieu de tester sur les fichiers originaux ;-(((

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Bonjour,

encore merci du temps que vous consacrez à ce problème ; les fichiers sont bien ceux indiqués dans mon mail d'origine et repris dans la réponse.
En entrée
- j'ai un fichier "base_client.csv" qui contient 5 champs et dont le contenu est :
1	dupont	11 rue des jasmins      oiseville       60
2       dubois  12 rue des oeillets     laville s mer   76
3       durand  13 rue des roses        nordville       59
4       dugnou  14 rue des lilas        sudville        34

avec comme séparateur la tabulation. Le premier champ est le N° de client et le 5° chanmp le département

-et un second fichier (en entrée) est "base_contrat.csv", qui contient lui aussi 5 champs et son contenu est :
1       1       0       titulaire       ?
1       2       1       bénéficiaire    ?
2       2       0       bénéficiaire    ?
3       3       0       titulaire       ?
3       4       1       titulaire       ?
3       5       2       titulaire       ?

avec comme séparateur la tabulation. Le premier champ est le N° de client et le 5° champ devrait contenir le département du client, mais est mal renseigné (?) ; il faudrait récupérer le département du client depuis le fichier "base_client.csv" en se synchronisant sur le N° de client.
Et pour ne pas lire à chaque ligne de base_contrat, tout le fichier base_client, il faut, je pense, faire une lecture synchronisée des deux fichiers ; c'est pourquoi ils sont triés tous les 2 sur le N°client. Je pense que awk est tout à fait approprié, mais je ne sais pas lire plusieirus fichiers (faire getline dans une boucle à l'intéreiur de la boucle principale awk ?)

Le résultat que je souhaiterais obtenir est un fichier de même structure que "base_contrat.csv", mais avec le département (5° champ) bien renseigné" ; soit :

1       1       0       titulaire       60
1       2       1       bénéficiaire    60
2       2       0       bénéficiaire    76
3       3       0       titulaire       59
3       4       1       titulaire       59
3       5       2       titulaire       59


Or, visiblement, quand je fais :
awk -F"\t" 'BEGIN{OFS="\t"}{if(!x[$1]){x[$1]=$5}else{$5=x[$1];print}}' base_clients.csv base_contrats.csv
je ne passe jamais dans le "else" ...

J'espère avoir été + clair
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 897
14 févr. 2010 à 23:01
Merci de répondre à la question !

0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
14 févr. 2010 à 23:03
Re,

les fichiers sont bien ceux indiqués dans mon mail d'origine et repris dans la réponse.
Ce ne sont pas des fichiers mais quelques lignes pour exemplifier.

J'espère avoir été + clair
Oui, mais ça ne suffit pas.
Mets tes fichiers dans une archive zip et ensuite dépose les sur cjoint.com et colle ici le lien.
Ce qui permettra de tester sur tes fichiers.
Sur les exemple qu'on copie depuis ccm il peut, par exemple, avoir ou il peut manquer des caractères non imprimables que ton fichier contient.

Puisqu'en faisant copier/coller depuis ccm j'ai ça

$ cat base_client.csv                  
1       dupont  11 rue des jasmins      oiseville       60
2       dubois  12 rue des oeillets     laville s mer   76
3       durand  13 rue des roses        nordville       59
4       dugnou  14 rue des lilas        sudville        34
$ cat base_contrat.csv                 
1       1       0       titulaire       ?
1       2       1       bénéficiaire    ?
2       2       0       bénéficiaire    ?
3       3       0       titulaire       ?
3       4       1       titulaire       ?
3       5       2       titulaire       ?
$ awk -F"\t" 'BEGIN{OFS="\t"}{if(!x[$1]){x[$1]=$5}else{$5=x[$1];print}}' base_clients.csv base_contrats.csv                 
1       1       0       titulaire       60
1       2       1       bénéficiaire    60
2       2       0       bénéficiaire    76
3       3       0       titulaire       59
3       4       1       titulaire       59
3       5       2       titulaire       59
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
14 févr. 2010 à 23:17
Re,

Si je fais la commande de jipicy j'ai ça

lami20j@debian:~$ cat -A base_client.csv 
1^Idupont^I11 rue des jasmins      oiseville       60$
2       dubois  12 rue des oeillets     laville s mer   76$
3       durand  13 rue des roses        nordville       59$
4       dugnou  14 rue des lilas        sudville        34$
lami20j@debian:~$ cat -A base_contrat.csv 
1       1       0       titulaire       ?$
1       2       1       bM-inM-ificiaire    ?$
2       2       0       bM-inM-ificiaire    ?$
3       3       0       titulaire       ?$
3       4       1       titulaire       ?$
3       5       2       titulaire       ?$


Chez toi c'est pareil?
0
Super_Didji Messages postés 4 Date d'inscription vendredi 12 février 2010 Statut Membre Dernière intervention 15 février 2010
14 févr. 2010 à 23:19
Yes,

voilà : https://www.cjoint.com/?coxsSvtXj4

Cordialement,

Super_Didji
0
Super_Didji Messages postés 4 Date d'inscription vendredi 12 février 2010 Statut Membre Dernière intervention 15 février 2010
14 févr. 2010 à 23:22
non la réponse que j'ai c'est bien ce que j'ai mis dans mon 2° mail.

J'ai envoyé les fichiers
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
14 févr. 2010 à 23:32
Re,

Pour le 1er fichier il n'y a pas que des tabulations entre les champs mais aussi des espaces entre
jasmins oiseville
par exemple

Ton 2ème fichiers il n'y a pas des tabulations mais des espaces.
Voilà pourquoi ça ne marche pas.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
14 févr. 2010 à 23:39
Re,

Voici à quoi ça rassemble tes fichiers selon la commande de jipicy

lami20j@debian:~/base$ cat -A *.csv           
1^Idupont^I11 rue des jasmins      oiseville       60$
2       dubois  12 rue des oeillets     laville s mer   76$
3       durand  13 rue des roses        nordville       59$
4       dugnou  14 rue des lilas        sudville        34$
1       1       0       titulaire       ?$
1       2       1       bM-inM-ificiaire    ?$
2       2       0       bM-inM-ificiaire    ?$
3       3       0       titulaire       ?$
3       4       1       titulaire       ?$
3       5       2       titulaire       ?$



Et voici comment devrait être pour que ça marche

lami20j@debian:~/base$ cat -A *.csv
1^Idupont^I11 rue des jasmins^Ioiseville^I60$
2^Idubois^I12 rue des oeillets^Ilaville s mer^I76$
3^Idurand^I13 rue des roses^Inordville^I59$
4^Idugnou  14 rue des lilas^Isudville^I34$
1^I1^I0^Ititulaire^I?$
1^I2^I1^IbM-inM-ificiaire^I?$
2^I2^I0^IbM-inM-ificiaire^I?$
3^I3^I0^Ititulaire^I?$
3^I4^I1^Ititulaire^I?$
3^I5^I2^Ititulaire^I?$


C'est un exemple que tu as construit?
Je le pense que oui, puisque par exemple même dans le 1er fichier à partir de la ligne 3 il y a des espaces comme séparateur.

Bref, tes exemples sont mal construit. ll y a des tabulations et des espaces en même temps.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
14 févr. 2010 à 23:42
Re,

Si tu pourras obtenir tes csv avec un séparateur point-virgule ça sera mieux je pense.
0
Super_Didji Messages postés 4 Date d'inscription vendredi 12 février 2010 Statut Membre Dernière intervention 15 février 2010
15 févr. 2010 à 00:10
Tu as tout à fait raison, j'ai corrigé mes "fichiers" qui j'avais écrit en texte pour exposer le problème, en mettant des blancs ; j'ai donc mis des | en séparateur et voilà qui est parfait :

didier@didier-desktop:~$ cat base_clients.csv
1|dupont|11rue des jasmins|oiseville|60
2|dubois|12 rue des oeillets|laville s mer|76
3|durand|13 rue des roses|nordville|59
4|dugnou|14 rue des lilas|sudville|34

didier@didier-desktop:~$ cat base_contrats.csv
1|1|0|titulaire|?
1|2|1|bénéficiaire|?
2|2|0|bénéficiaire|?
3|3|0|titulaire|?
3|4|1|titulaire|?
3|5|2|titulaire|?

didier@didier-desktop:~$ awk -F"|" 'BEGIN{OFS="|"}{if(!x[$1]) {x[$1]=$5} else {$5=x[$1];print}}'
base_clients.csv base_contrats.csv

1|1|0|titulaire|60
1|2|1|bénéficiaire|60
2|2|0|bénéficiaire|76
3|3|0|titulaire|59
3|4|1|titulaire|59
3|5|2|titulaire|59
didier@didier-desktop:~$

Cest formidable et merci à tous Lami20j et Jipicy

Je vais essayé de faire un test en randeur nature dès demain et vous tiens au courant.

Cordialement,

Super_Didji
0