Fusion de deux tableaux avec perl

Résolu
deniss92 Messages postés 41 Statut Membre -  
deniss92 Messages postés 41 Statut Membre -
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
Configuration: Windows XP
Internet Explorer 7.0

6 réponses

  1. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    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
    1. deniss92 Messages postés 41 Statut Membre 1
       
      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
  2. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    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
    1. deniss92 Messages postés 41 Statut Membre 1
       
      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
  3. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Salut,

    affiche ton script, avec les modifications
    0
  4. deniss92 Messages postés 41 Statut Membre 1
     
    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
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    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
  7. deniss92 Messages postés 41 Statut Membre 1
     
    Ok

    Merci de ta gentillesse.
    @+
    0