IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Comparer 2 tableaux de hash sur une clé précise


Sujet :

Langage Perl

  1. #1
    Membre à l'essai
    Homme Profil pro
    Intégrateur d'exploitation
    Inscrit en
    Avril 2014
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Intégrateur d'exploitation
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2014
    Messages : 17
    Points : 14
    Points
    14
    Par défaut Comparer 2 tableaux de hash sur une clé précise
    Bonjour,

    je cherche à comparer 2 tableaux de hash afin de connaître les éléments présents dans 1 seul des tableaux, les stocker dans un hash et connaître l'action à faire sur ces éléments.

    Mes 2 tableaux de hash ont la même structure, la seule chose que je dois vérifier, c'est la présence d'une valeur de clé précise : hostname.

    Un extrait des print Dumper des 2 tableaux :

    @data_j :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    $VAR1 = [
              {
                'date_maj' => '2016/05/18',
                'etat' => 'Operationnel',
                'env' => 'HPROD',
                'environnement' => 'DEVELOPPEMENT',
                'upm' => 'UPM_XXXXXX',
                'hostname' => 'SRV1',
                'os' => 'UNX'
              },
              {
                'date_maj' => '2016/05/18',
                'etat' => 'Operationnel',
                'env' => 'HPROD',
                'environnement' => 'DEVELOPPEMENT',
                'upm' => 'UPM_XXXXXX',
                'hostname' => 'SRV2',
                'os' => 'UNX'
              },
    (...)
    ]
    @data_w :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    $VAR1 = [
              {
                'date_maj' => '2016/05/18',
                'etat' => 'Operationnel',
                'env' => 'HPROD',
                'environnement' => 'DEVELOPPEMENT',
                'upm' => 'UPM_XXXXXX',
                'hostname' => 'SRV2',
                'os' => 'UNX'
              },
              {
                'date_maj' => '2016/05/18',
                'etat' => 'Operationnel',
                'env' => 'HPROD',
                'environnement' => 'DEVELOPPEMENT',
                'upm' => 'UPM_XXXXXX',
                'hostname' => 'SRV5',
                'os' => 'UNX'
              },
    (...)
    ]
    J'aimerais arriver à produire un tableau de hash qui aurait cette tête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [ HOSTNAME => { env =>,
                             os =>,
                             action =>
                           }
    ]
    et donc au final avec mon cas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [ 'SRV1' => { env => 'HPROD',
                       os => 'UNX'
                       action => 'DEL'
                    },
      'SRV5' => { env => 'HPROD',
                       os => 'UNX'
                       action => 'ADD'
                    }
    ]
    Parce qu'au final, je dois construire un fichier plat de la sorte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UNX;SRV1;HPROD;DEL
    UNX;SRV5;HPROD;ADD

    J'ai commencé à écrire ceci mais je butte sur la récupération des valeurs des hash. Pour le moment j'ai juste cherché à créer mon troisième hash mais c'est la cata, j'ai vraiment du mal ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    sub prepare_getlog() {
      my ($this,$data) = @_;
      my @data_j = $this->{data};
     
      print Dumper (@data_j);
     
      $this->{file} = $this->{histo_dir}.strftime("extraction_assetdb.%y%m%d.csv", localtime(time() - 604800));
      $this->parse($this->{file});
      my @data_w = $this->{data};
      print Dumper (@data_w);
     
      print "Difference entre les 2 hash\n";
      foreach my $h (@data_w) {
        my %info_getlog;
        foreach my $h2 (@{$h}) {
          my $cle = $h2->{hostname};
          $info_getlog{os} = $h2->{os};
          $info_getlog{env} = $h2->{env};
          $info_getlog{action} = 'DEL';
          $this->{getlog}->{$cle} = \%info_getlog;
        }
      }
    }

    Je ne vous cache pas qu'un petit coup de pouce serait la bienvenue, à minima sur la méthode pour comparer 2 valeurs de clé de 2 hash


    Merci à vous,

    CH

  2. #2
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Bonsoir,

    je ne suis pas sûr de bien comprendre ce que tu cherches à faire, mais voici déjà une façon de réorganiser tes données pour les rendre plus faciles à utiliser:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    use strict;
    use warnings;
    use Data::Dumper;
     
    my @array = 
        (
              {
                'date_maj' => '2016/05/18',
                'etat' => 'Operationnel',
                'env' => 'HPROD',
                'environnement' => 'DEVELOPPEMENT',
                'upm' => 'UPM_XXXXXX',
                'hostname' => 'SRV1',
                'os' => 'UNX'
              },
              {
                'date_maj' => '2016/05/18',
                'etat' => 'Operationnel',
                'env' => 'HPROD',
                'environnement' => 'DEVELOPPEMENT',
                'upm' => 'UPM_XXXXXX',
                'hostname' => 'SRV2',
                'os' => 'UNX'
              },
          );
     
    my %hash;
     
    for my $h_ref (@array) {
    	my $key = $h_ref->{hostname};
    	my $env = $h_ref->{env};
    	$hash{$key} = {env => $env, action => ""}
    }
     
    print Dumper \%hash;
    Ce qui imprime:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    $ perl hashrefenv.pl
    $VAR1 = {
              'SRV2' => {
                          'env' => 'HPROD',
                          'action' => ''
                        },
              'SRV1' => {
                          'env' => 'HPROD',
                          'action' => ''
                        }
            };
    Si tu fais la même chose avec l'autre tableau, tu obtiendras un hachage du même type. Il est ensuite facile de parcourir les clefs d'un des hachages et de voir les serveurs qui existent dans l'un et pas dans l'autre, et décider de l'action à entreprendre.

    En supposant que j'aie compris ce que tu cherches à faire... ce qui n'est pas certain.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Intégrateur d'exploitation
    Inscrit en
    Avril 2014
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Intégrateur d'exploitation
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2014
    Messages : 17
    Points : 14
    Points
    14
    Par défaut
    Bonjour Lolo78,

    merci pour ton retour.
    Il est vrai que j'ai du mal à exprimer en perl, ça fait trop longtemps que je n'en ai pas écrit, et encore c'était du "sur le tas" ...

    Je vais tester ton bout de code pour créer les hash dont j'ai besoin pour faire mes comparaisons.

    Sinon tu as bien compris mon besoin : comparer et extraire les différences entre les 2 hash

    Edit :

    petite erreur rencontrée : Bad index while coercing array into hash at /apps/sibr/injecteur/includes/scanItam.pm line 167, <FILE> line 52003.

    Le code qui me permet de créer mes listes est le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    # Fonction parse_crs pour parser les fichiers de type crs
    # alimente la variable $this->{data}
    # hash {cle => hash{hostname => "parva...", serveur => ""}, ... }
    # la cle est la concatenation du nom_du_serveur._nom_de_l_serveur.date.heure
    sub parse() {
      my ($this,$file) = @_;
     
      $this->{serveurs} = {};
     
      my $csv = Text::CSV->new({sep_char => ';', binary => 1});
      open (FILE, $file) || die "ouverture du fichier $file";
      my $numLigne = 0;
      while(my $ligne = <FILE>) {
        chomp($ligne); $numLigne++;
        my @field; my %field;
        if ($csv->parse($ligne)) {
          @field = $csv->fields;
          my $i = 0;
          my %data;
          foreach my $cle (@{$this->{cle_serveur}}) {
            $data{$cle} = $field[$i];
            $i++;
          }
          my $validateur = validateurItam->new(\%data);
          if ($validateur->isValid()) {
            $this->{serveurs}->{$numLigne} = \%data;
          }
        }
      }
     
      # Formatage des data
      return $this->format_data();
    }
     
     
    # Fonction format
    # prepare les données, reformatage  pour les serveurs sans appli
    sub format_data() {
      my $this = shift;
     
      $this->{data} = [];
     
      for my $key ( keys %{$this->{serveurs}} ) {
        my %data;
        my $serveur = $this->{serveurs}->{$key};
     
        $data{hostname} = uc($$serveur{hostname});
        $data{environnement} = $$serveur{environnement};
        $data{etat} = $$serveur{etat};
        $data{upm} = $$serveur{upm};
        $data{os} = $$serveur{os};
     
        # Champs pour GETLOG
        my $getlog = getlogItam->new(\%data);
        $data{os} = $getlog->formatOs();
        $data{env} = $getlog->formatEnv();
     
        # Rajout de la date de mise a jour
        $data{date_maj} = Custom_date->getDateJour();
     
        push(@{$this->{data}}, \%data);
      }
    }

    Ce code ne peut être modifié car il me permet aujourd'hui de réaliser des actions. Je récupère donc juste le résultat qu'il donne, c'est à dire $this->{data}, qui semble être une liste ?

  4. #4
    Membre à l'essai
    Homme Profil pro
    Intégrateur d'exploitation
    Inscrit en
    Avril 2014
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Intégrateur d'exploitation
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2014
    Messages : 17
    Points : 14
    Points
    14
    Par défaut
    Auto-réponse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
      for my $h_ref (@data_j) {
        foreach my $h2 (@{$h_ref}) {
          my $key = $h2->{hostname};
          my $env = $h2->{env};
          my $os = $h2->{os};
          $hash_j{$key} = {env => $env, os => $os};
        }
      }
    Ce qui me donne le même résultat que toi Lolo78

    Parfait !

    Je laisse le poste ouvert car j'aurais peut-être encore besoin de vos lumières

  5. #5
    Membre à l'essai
    Homme Profil pro
    Intégrateur d'exploitation
    Inscrit en
    Avril 2014
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Intégrateur d'exploitation
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2014
    Messages : 17
    Points : 14
    Points
    14
    Par défaut
    Et voila, c'est terminé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
      # 2 - Construisons le 3ieme hash avec les elements de hash_j qui ne sont pas dans hash_w (ADD) et inversement (DEL)
      my %hash;
      $this->{log}->info("Gestion automatique des ajouts/retraits serveurs dans confs GETLOG");
      foreach (keys %hash_w) {
        if (! exists $hash_j{$_}) {
          my $env = $hash_w{$_}->{env};
          my $os = $hash_w{$_}->{os};
          $hash{$_} = {env => $env, os => $os, action => 'DEL'};
       }
       print "removed $_\n" unless exists $hash_j{$_};
      }
      foreach (keys %hash_j) {
        if (! exists $hash_w{$_}) {
          my $env = $hash_j{$_}->{env};
          my $os = $hash_j{$_}->{os};
          $hash{$_} = {env => $env, os => $os, action => 'ADD'};
       }
       print "added $_\n" unless exists $hash_w{$_};
      }
     
      # 3 - Maintenant on va generer le fichier serveur_getlog.list avec le %hash !!
      my $file = $this->{getlog_dir}.$this->{getlog_list};
      rename $file, $file.".old";
      open (FILE, ">>", $file) || die "ouverture du fichier $file";
      print FILE "# Update automatique du ".Custom_date->getDateJour()."\n";
      foreach (keys %hash) {
        my $env = $hash{$_}->{env};
        my $os = $hash{$_}->{os};
        my $action = $hash{$_}->{action};
        print FILE "$os;$_;$action;$env;ALL;vxxx\n";
      }

  6. #6
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Il me semblait aussi que le plus difficile pour toi était de réorganiser les données pour les rendre plus faciles à utiliser, c'est pour cela que c'est ce que j'ai proposé comme base d'une solution. Tu as manifestement très bien compris le parti à en tirer.

    Bonne continuation.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2010] VBA : Automatiser plusieurs tableaux croisés dynamiques sur une même page
    Par damoko dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 07/07/2015, 11h52
  2. Comparer deux tableaux et travail sur la BDD
    Par Razgort dans le forum Langage
    Réponses: 0
    Dernier message: 06/08/2012, 15h26
  3. Réponses: 2
    Dernier message: 06/04/2010, 14h24
  4. [Tableaux] Passer paramètre sur une autre page
    Par lafmart dans le forum Langage
    Réponses: 1
    Dernier message: 04/02/2007, 16h29
  5. [Serial] Commencer sur une valeur précise
    Par e1lauren dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 31/07/2006, 14h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo