Fusion de deux tableaux avec perl

Résolu/Fermé
deniss92 Messages postés 39 Date d'inscription vendredi 3 août 2007 Statut Membre Dernière intervention 15 septembre 2013 - 20 août 2007 à 00:54
deniss92 Messages postés 39 Date d'inscription vendredi 3 août 2007 Statut Membre Dernière intervention 15 septembre 2013 - 23 août 2007 à 17:38
Bonjour,

Je demarre la programmation perl avec deux problèmes :

1er problème la fusion de deux fichiers

fichier1

Numero;Nom
0001;toto
0002;titi
0003;tata

fichier2

numero;materiel
0001;Latitude D800
0001;HP 2200
0001;scanner HP
0002; Maestro 191
0002;iMedia 9668
0003;SW86-P-012

le fichier final "fusion" devra donner ceci :

numero;nom;materiel
0001;toto;Latitude D800
0001;toto;HP 2200
0001;toto;scanner HP
0002;titi;Maestro 191
0002;titi;iMedia 9668
0003;tata;SW86-P-012

2ème problème :
Le but final du fichier fusionné est de transformer les doublons en colonne supplémentaire comme suit :

numero;nom;materiel1;materiel2;materiel3
0001;toto;Latitude D800;HP 2200;scanner HP
0002;titi;Maestro 191;iMedia 9668 ;
0003;tata;SW86-P-012

Merci d'avance à vous tous.

Denis
A voir également:

6 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 567
20 août 2007 à 13:48
Salut,

tu peux obtenir le fichier final directement (je n'ai pas testé :-)
#!/usr/bin/perl
use strict;use warnings;

open FIC1,"fichier1" or die "E/S : $!\n";
open FIC2,"fichier2" or die "E/S : $!\n";
open RES,">fusion"   or die "E/S : $!\n";
my %h;

while(<FIC1>){
  next unless /^\d/;
  /(.*);(.*)/;
  push @$h{$1}},$2;
}

while(<FIC1>){
  next unless /^\d/; 
  /(.*);(.*)/;
  push @{$h{$1}},$2;
}

print RES "numero;nom;materiel1;materiel2;materiel3\n";
foreach my $k(sort keys %h)'
  print RES "$k", map { ";$_" } @{$h{$k}}, "\n";
} 
0
deniss92 Messages postés 39 Date d'inscription vendredi 3 août 2007 Statut Membre Dernière intervention 15 septembre 2013 1
20 août 2007 à 14:52
RE

Merci d'avoir répondu aussi rapidement. La procédure que tu m'as envoyé fonctionne. Toutefois, je ne comprends pas bien la ligne "push @{$h{$1}},$2" ?
Si j'avais les deux fichiers en 3 colonnes, ça marcherait quand meme ? Je demande cela, car je ne maitrise pas encore très bien le hachage. Est ce que je peux mettre @{$h{$1}},$2,$3. C'est vrai que dans tous les exemples que j'ai vu pour le moment, la structure est :
%h=(cle1=>valeur1,
cle2 =>valeur2)
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 567
20 août 2007 à 15:06
Re,

Est ce que je peux mettre @{$h{$1}},$2,$3.
la syntaxe est push TABLEAU,LISTE
donc tu peux écrire
push @{$h{$1}},($2,$3)


C'est vrai que dans tous les exemples que j'ai vu pour le moment, la structure est :
%h=(cle1=>valeur1,
cle2 =>valeur2)


Ici il s'agit d'un hash de tableaux ou chaque clé a comme valeur un tableau anonyme

%h = {
              cle1 => [...],
              cle2 => [...],
};
donc
$h{cle1} = [....];est comme pour le tableau on utilise @ et le nom de tableau c'est la clé alors je peux écrire
@{$h{cle1}}
pour traiter les éléments du tableau
0
deniss92 Messages postés 39 Date d'inscription vendredi 3 août 2007 Statut Membre Dernière intervention 15 septembre 2013 1
23 août 2007 à 12:59
Bonjour

J'ai essayé de mettre en oeuvre l'instruction push @{$h{$1}},($2,$3,$4) en créant le fichier suivant :

fichier 1

numero;Nom;rue;CP;Ville
0001;toto;70 rue de Reuilly;75592;paris
0002;titi;18 rue volant;92000;Nanterre
0003;tata;135 avenue voltaire;75011;Paris

fichier2

numero;materiel
0001;Latitude D800
0001;HP 2200
0001;scanner HP
0002;Maestro 191
0002;iMedia 9668
0003;SW86-P-012

fichier "fusion"

numero;nom;rue;CP;Ville;materiel1;materiel2;materiel3
0001;toto;70 rue de Reuilly;75592;paris;Latitude D800;HP 2200;scanner HP;
0002;titi;18 rue volant;92000;Nanterre;Maestro 191;iMedia 9668;
0003;tata;135 avenue voltaire;75011;Paris;SW86-P-012;

Mais je n'arrive pas à faire tourner le programme modifié.

Merci d'avance

Denis
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 567
23 août 2007 à 13:14
Salut,

affiche ton script, avec les modifications
0
deniss92 Messages postés 39 Date d'inscription vendredi 3 août 2007 Statut Membre Dernière intervention 15 septembre 2013 1
23 août 2007 à 15:01
Voici le script

#!/usr/bin/perl
use strict;use warnings;

open FIC1,"fichier1" or die "E/S : $!\n";
open FIC2,"fichier2" or die "E/S : $!\n";
open RES,">fusion1" or die "E/S : $!\n";
my %h;

while(<FIC1>){
next unless /^\d/;
/(.*);(.*)/;
push @{$h{$1}},($2,$3,$4,$5);
}
while(<FIC2>){
next unless /^\d/;
/(.*);(.*)/;
push @{$h{$1}},$2;
}

print RES "numero;nom;materiel1;materiel2;materiel3;observation\n";
foreach my $k(sort keys %h){
print RES "$k", map { ";$_" } @{$h{$k}}, "\n";
}
0

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

Posez votre question
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 567
23 août 2007 à 15:11
Salut,

c'est normal
pour chaque capture donc (.*) une variable sera remplie
dans ton cas tu n'as que $1 et $2

pour avoir
$3, $4, $5
il faut écrire
while(<FIC1>){ 
next unless /^\d/; 
/(.*);(.*);(.*);(.*);(.*)/; 
push @{$h{$1}},($2,$3,$4,$5); 
} 

0
deniss92 Messages postés 39 Date d'inscription vendredi 3 août 2007 Statut Membre Dernière intervention 15 septembre 2013 1
23 août 2007 à 17:38
Ok

Merci de ta gentillesse.
@+
0