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 :

Récupération de valeurs dans un fichier redirigées dans un hash


Sujet :

Langage Perl

  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2013
    Messages
    326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2013
    Messages : 326
    Points : 156
    Points
    156
    Par défaut Récupération de valeurs dans un fichier redirigées dans un hash
    Bonjour à tous,

    Mon besoin est le suivant, dans /etc/hosts, j'ai besoin de récupérer l'ensemble des nom de machines + @IP
    Exemple du /etc/hosts :
    x.x.x.x machineA
    y.y.y.y machineB
    z.z.z.z machineC

    Je voudrais rentrer ces valeurs dans une table de hash, par exemple :
    %hash = [[x.x.x.x => machineA], [y.y.y.y => machineB], [z.z.z.z => machineC]]

    Est ce que déjà tout ce que je raconte plus haut est possible ? (je pense que oui d'après les recherches que j'ai fais). La 2ème question est de savoir si je peux retrouver l'@IP à partir d'un nom de machine ? Et est-ce qu'au final cette méthode tient la route/est optimisée ?

    Merci d'avance

  2. #2
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Taisha:~/perl/forum $ cat sample
    # commentaire
    x.x.x.x machineA
    # commentaire additionnel
    y.y.y.y machineB
    z.z.z.z machineC
    Taisha:~/perl/forum $ ETCHOSTS=sample perl -E '%h = map { chomp; reverse split} grep { !/^#/ } do {local @ARGV = $ENV{ETCHOSTS} || q{/etc/hosts}; <> }; say "$_: $h{$_}" for @ARGV' machineB autre machineC
    machineB: y.y.y.y
    autre: 
    machineC: z.z.z.z
    Taisha:~/perl/forum $
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  3. #3
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Désolé c'est parti tout seul...

    Si tu veux gérer les alias par exemple
    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
    Taisha:~/perl/forum $ cat sample2
    #
    # Fichier /etc/hosts - Affecte des noms d'hotes a des adresses IP.
    #
    # Syntaxe : IP    nom d'hote canonique    alias
    #
    # Pour bouclage
    #
     
    127.0.0.1    localhost
     
    #
    # Autres hotes
    #
     
    192.168.1.2    nougat.chez.moi        nougat
    192.168.1.1    zecastor.chez.moi      zecastor
    192.168.1.4    tarsier.chez.moi       tarsier
    Taisha:~/perl/forum $
    tu peux utiliser quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Taisha:~/perl/forum $ ETCHOSTS=sample2 perl -E '%h = map { my ($ip, @names) = split; map { ($_, $ip) } @names } grep {!/^#/ } do {local @ARGV = $ENV{ETCHOSTS} || q{/etc/hosts}; <> }; say "$_: $h{$_}" for @ARGV' nougat choucroute tarsier.chez.moi
    nougat: 192.168.1.2
    choucroute: 
    tarsier.chez.moi: 192.168.1.4
    Taisha:~/perl/forum $
    ETCHOSTS est une variable d'environnement qui indique le fichier hosts à lire. Si elle n'est pas définie on lit /etc/hosts.

    do {local @ARGV = $ENV{ETCHOSTS} || q{/etc/hosts}; <> } est une astuce pour éviter d'ouvrir explicitement le fichier. On assigne localement à @ARGV la liste à un élément égal au nom du fichier à ouvrir ( $ENV{ETCHOSTS} || q{/etc/hosts}). On est en contexte de liste , donc <> va lire l'ensemble des lignes de tous les fichiers spécifiés dans le @ARGV local, en l'occurence il n'y en a qu'un et c'est celui qui nous intéresse.

    grep {!/^#/ } va filtrer cette liste en ne laissant passer que les lignes qui ne commencent pas par le catactère #.

    map { my ($ip, @names) = split; map { ($_, $ip) } @names } va produire pour chaque ligne restante une liste de listes (nom, ip) pour chacun des noms figurant dans la ligne (le nom canonique et les alias s'il y en a).

    Ces différentes listes sont aplaties lors de l'affectation à %h. le tour est joué.

    say "$_: $h{$_}" for @ARGV affiche le résultat pour chacun des noms passés en paramètre au script (ici nougat choucroute tarsier.chez.moi). On voit que choucroute est inconnue au bataillon.

    Si tu as des questions n'hésite pas
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  4. #4
    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
    Citation Envoyé par ciols Voir le message

    Je voudrais rentrer ces valeurs dans une table de hash, par exemple :
    %hash = [[x.x.x.x => machineA], [y.y.y.y => machineB], [z.z.z.z => machineC]]

    Est ce que déjà tout ce que je raconte plus haut est possible ? (je pense que oui d'après les recherches que j'ai fais).
    Oui, bien sûr que c'est possible, sauf que ta représentation du hash n'est pas conforme à la syntaxe Perl. Ce serait plutôt:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    %hash = (x.x.x.x => "machineA", y.y.y.y => "machineB", z.z.z.z => "machineC");
    Citation Envoyé par ciols Voir le message
    La 2ème question est de savoir si je peux retrouver l'@IP à partir d'un nom de machine ? Et est-ce qu'au final cette méthode tient la route/est optimisée ?
    Dans ce cas il vaut mieux faire le contraire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    %hash = (machineA => "x.x.x.x",  machineB => "y.y.y.y"", machineC => "z.z.z.z");
    Dans ce cas, pour trouver une IP, tu fais simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    my $IP = $hash{machineA};
    et un lookup dans un hachage est très rapide et aussi optimisé que tu puisses le faire.

    Pour alimenter le hash, voici un exemple à la ligne de commande:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    $ echo "x.x.x.x machineA
    > y.y.y.y machineB
    > z.z.z.z machineC" | perl -MData::Dumper -ne '
    >     my  @s = split;
    >     $hash{$s[1]} = $s[0];
    >     END{ print Dumper \%hash; }
    > '
    $VAR1 = {
              'machineB' => 'y.y.y.y',
              'machineA' => 'x.x.x.x',
              'machineC' => 'z.z.z.z'
            };

  5. #5
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2013
    Messages
    326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2013
    Messages : 326
    Points : 156
    Points
    156
    Par défaut
    Merci beaucoup pour vos réponses ultra détaillées !!!

    Je vais me pencher sur ce que vous me proposez et je reviendrai vers vous en cas de problème !

    En tout cas, merci encore !

  6. #6
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2013
    Messages
    326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2013
    Messages : 326
    Points : 156
    Points
    156
    Par défaut
    En relisant tout cela, je me rends compte que je me suis mal exprimé au niveau des besoins de ma recherche.

    Je voudrais pouvoir retrouver l'@ip en fonction du nom de la machine mais aussi pouvoir retrouver le nom de la machine en connaissant son @ip.

    Y'a t'il une méthode existante qui permettent de le faire ? Sinon je pense créé deux hash :

    Un comme ça :
    $VAR1 = {
    'machineB' => 'y.y.y.y',
    'machineA' => 'x.x.x.x',
    'machineC' => 'z.z.z.z'
    };
    et l'autre comme ça :
    $VAR1 = {
    'y.y.y.y' => 'machineB',
    'x.x.x.x' => 'machineA',
    'z.z.z.z' => 'machineC'
    };

  7. #7
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par ciols Voir le message
    Je voudrais pouvoir retrouver l'@ip en fonction du nom de la machine mais aussi pouvoir retrouver le nom de la machine en connaissant son @ip.
    Tu peux utiliser deux hashs comme tu le proposes si la correspondance nom / ip est biunivoque. Mais dans la vraie vie une machine peut avoir plusieurs ip et plusieurs noms... Dans ce cas il vaudrait peut-être mieux quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    %n2i = ( 
        'machineA' => [ 'x.x.x.x', 't.t.t.t' ],
        'machineB' => [ 'y.y.y.y' ],
        'machineC' => [ 'z.z.z.z' ],
        'aliasA'   => [ 'x.x.x.x', 't.t.t.t' ],
        'aliasB'   => [ 'y.y.y.y' ],
    );
    %i2n = (
        'x.x.x.x' => [ 'machineA', 'AliasA' ],
        'y.y.y.y' => [ 'machineB', 'AliasB' ],
        'z.z.z.z' => [ 'machineC' ],
        't.t.t.t' => [ 'machineA', 'AliasA' ],
    );
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  8. #8
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2013
    Messages
    326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2013
    Messages : 326
    Points : 156
    Points
    156
    Par défaut
    J'ai testé ta solution cmcmc, et j'arrive à avoir mon hash avec en clé le nom et en valeur l'ip.

    Cependant j'ai un souci quand je reverse ton code pour avoir le hash avec en clé l'ip et en valeur l'ip, voici le code que j'ai produis :

    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
    sub recup_nom_IP {
      %nom2ip = map { 
        my ($ip, @names) = split; map {
          ($_, $ip)
        } @names;
      } grep {!/^#/ }
      do { local @ARGV = $ENV{ETCHOSTS} || q{/etc/hosts}; <> };
      foreach (@ARGV) {
        print FILE "$_";
      }
      return %nom2ip;
    }
     
    sub recup_IP_nom {
      %ip2nom = map { 
        my ($ip, $names) = split; map {
          ($_, $names)
        } $ip;
      } grep {!/^#/ }
      do { local @ARGV = $ENV{ETCHOSTS} || q{/etc/hosts}; <> };
      foreach (@ARGV) {
        print FILE "$_";
      }
      return %ip2nom;
    }
     
    my %test = recup_IP_nom();
    foreach my $k (keys(%test)) {
       print "Clef=$k Valeur=$test{$k}\n";
    }
    PS : Mon perl est en 5.8.8 c'est pour cela que je n'utilise pas say !

    EDIT : Ca marche presque, il fallait que je remplace @names par $names ! Cependant, lors de l'exécution du script, j'ai pas mal d'erreurs, dixit ci-dessous :
    Use of uninitialized value in list assignment at ./conf_pcrf.pl line 79, <> line 20.
    Use of uninitialized value in list assignment at ./conf_pcrf.pl line 79, <> line 20.
    Use of uninitialized value in list assignment at ./conf_pcrf.pl line 79, <> line 20.
    Use of uninitialized value in list assignment at ./conf_pcrf.pl line 79, <> line 20.
    print() on unopened filehandle FILE at ./conf_pcrf.pl line 81, <> line 20.
    print() on unopened filehandle FILE at ./conf_pcrf.pl line 81, <> line 20.
    print() on unopened filehandle FILE at ./conf_pcrf.pl line 81, <> line 20.
    print() on unopened filehandle FILE at ./conf_pcrf.pl line 81, <> line 20.
    print() on unopened filehandle FILE at ./conf_pcrf.pl line 81, <> line 20.
    print() on unopened filehandle FILE at ./conf_pcrf.pl line 81, <> line 20.
    Use of uninitialized value in concatenation (.) or string at ./conf_pcrf.pl line 88, <> line 20.
    Clef= Valeur=
    ligne 79 =
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    do { local @ARGV = $ENV{ETCHOSTS} || q{/etc/hosts}; <> };
    ligne 81 =Juste après cette ligne j'obtiens bien toutes mes valeurs correctement.

    EDIT 2 : Pour la première fonction quand je veux faire l'affichage des valeurs, je fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    my %test = recup_nom_IP();
    foreach my $v (keys(%test)) {
      print " valeur = $test{$v}\n";
      push(@tabIP,$v);
    }
    Et j'obtiens plusieurs fois la même @ip alors que dans /etc/hosts elle n'y ait qu'une fois. J'ai du faire une erreur mais je n'arrive pas à la trouver

  9. #9
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par ciols Voir le message
    J'ai testé ta solution cmcmc, et j'arrive à avoir mon hash avec en clé le nom et en valeur l'ip.

    Cependant j'ai un souci quand je reverse ton code pour avoir le hash avec en clé l'ip et en valeur l'ip, voici le code que j'ai produis :

    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
    sub recup_nom_IP {
      %nom2ip = map { 
        my ($ip, @names) = split; map {
          ($_, $ip)
        } @names;
      } grep {!/^#/ }
      do { local @ARGV = $ENV{ETCHOSTS} || q{/etc/hosts}; <> };
      foreach (@ARGV) {
        print FILE "$_";
      }
      return %nom2ip;
    }
     
    sub recup_IP_nom {
      %ip2nom = map { 
        my ($ip, $names) = split; map {
          ($_, $names)
        } $ip;
      } grep {!/^#/ }
      do { local @ARGV = $ENV{ETCHOSTS} || q{/etc/hosts}; <> };
      foreach (@ARGV) {
        print FILE "$_";
      }
      return %ip2nom;
    }
     
    my %test = recup_IP_nom();
    foreach my $k (keys(%test)) {
       print "Clef=$k Valeur=$test{$k}\n";
    }
    commence par éliminer les lignes 8,9,10 et 21,22,23 ci-dessus. Elles correspondent au code de 'démonstration' de mon uniligne et n'ont rien à faire dans ces fonctions.

    Ensuite, dans recup_IP_nom, il faut bien comprendre que tu ne retiens que le premier nom figurant après l'IP. Autrement dit, tu oublies les alias s'il y en a (c'est peut-être délibéré, mais dans ce cas tes deux hashes ne sont pas symétriques). La map impriqué n'est plus nécessaire, et ta fonction est équivalente à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    sub recup_IP_nom {
      %ip2nom = map { 
        my ($ip, $nom_canonique, @alias) = split; 
        ($ip, $nom_canonique); 
      } grep {!/^#/ }
      do { local @ARGV = $ENV{ETCHOSTS} || q{/etc/hosts}; <> };
      return %ip2nom;
    }
    où on voit bien qu'on a ignoré les alias...

    début de update1
    en fait dans la fonction amendée ci-dessus, l'affectation à %ip2nom ne sert à rien. On peut la simplifier en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    sub recup_IP_nom {
      map { 
        my ($ip, $nom_canonique, @alias) = split; 
        ($ip, $nom_canonique)
      } grep {!/^#/ }
      do { local @ARGV = $ENV{ETCHOSTS} || q{/etc/hosts}; <> }
    }
    idem pour recup_nom_IP. La version ci-dessous ignore également les alias :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    sub recup_nom_IP {
      map { 
        my ($ip, $nom_canonique, @alias) = split;
        ($nom_canonique, $ip)
      } grep {!/^#/ }
      do { local @ARGV = $ENV{ETCHOSTS} || q{/etc/hosts}; <> }
    }
    fin de update1

    Citation Envoyé par ciols Voir le message
    Use of uninitialized value in list assignment at ./conf_pcrf.pl line 79, <> line 20.
    ligne 79 = do { local @ARGV = $ENV{ETCHOSTS} || q{/etc/hosts}; <> };
    Bizarre. Peut-être un problème de 5.8.8 (je ne l'ai pas sous la main).
    Essaie de remplacer cette ligne par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    do { local @ARGV = exists($ENV{ETCHOSTS}) ? $ENV{ETCHOSTS} : "/etc/hosts"; <> };
    Citation Envoyé par ciols Voir le message
    EDIT 2 : Pour la première fonction quand je veux faire l'affichage des valeurs, je fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    my %test = recup_nom_IP();
    foreach my $v (keys(%test)) {
      print " valeur = $test{$v}\n";
      push(@tabIP,$v);
    }
    Et j'obtiens plusieurs fois la même @ip alors que dans /etc/hosts elle n'y ait qu'une fois. J'ai du faire une erreur mais je n'arrive pas à la trouver
    Si tu as des alias c'est normal, tu verra chaque IP apparaître 1 fois (pour le nom canonique) + autant de fois qu'il y a d'alias


    Si tu dois calculer les deux hashes, tu peux peut-être le faire dans une même fonction. Par exemple (en traitant les alias et éventuellement les ip multiples) :

    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
    Taisha:~/perl/forum $ ETCHOSTS=sample2 perl -MData::Dump -e '
        sub build_hashes {
          my ($i2n, $n2i);
          local @ARGV = exists($ENV{ETCHOSTS}) ? $ENV{ETCHOSTS} : "/etc/hosts";
          while (<>) {
            next if /^\s*(#|$)/;
            my ($ip, @names) = split;
            $i2n->{$ip} = [ @names ];
            push @{$n2i->{$_}}, $ip for @names;
          }
          ($i2n, $n2i);
        }
        my ($i2n, $n2i) = build_hashes();
        print "\$i2n = "; dd $i2n;
        print "\$n2i = "; dd $n2i;
        for (@ARGV) {
          print "$_ : @{ m/^\d+\.\d+\.\d+\.\d+$/ ? $i2n->{$_} : $n2i->{$_} }\n";
        }
      ' nougat choucroute tarsier.chez.moi 192.168.1.1
    $i2n = {
      "127.0.0.1"   => ["localhost"],
      "192.168.1.1" => ["zecastor.chez.moi", "zecastor"],
      "192.168.1.2" => ["nougat.chez.moi", "nougat"],
      "192.168.1.4" => ["tarsier.chez.moi", "tarsier"],
    }
    $n2i = {
      "localhost"         => ["127.0.0.1"],
      "nougat"            => ["192.168.1.2"],
      "nougat.chez.moi"   => ["192.168.1.2"],
      "tarsier"           => ["192.168.1.4"],
      "tarsier.chez.moi"  => ["192.168.1.4"],
      "zecastor"          => ["192.168.1.1"],
      "zecastor.chez.moi" => ["192.168.1.1"],
    }
    nougat : 192.168.1.2
    choucroute : 
    tarsier.chez.moi : 192.168.1.4
    192.168.1.1 : zecastor.chez.moi zecastor
    Taisha:~/perl/forum $
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  10. #10
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2013
    Messages
    326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2013
    Messages : 326
    Points : 156
    Points
    156
    Par défaut
    Merci encore une fois pour tes réponses aussi détaillées que complètes.

    Je ne suis pas encore sûr d'avoir besoin ou non des alias. Dans un premier temps je vais les garder pour avoir un maximum de flexibilité.

    Les deux hash de ta dernière fonction me perturbent un peu car il n'y a pas de % devant mais à part ça tout roule !

    Je n'arrive pas à exploiter les deux hash qui sont fabriqué avec la fonction :/, j'arrive à les afficher avec print Dumper($i2n), je vois bien que ce sont des hash avec les couples clé/valeurs mais impossible d'en tirer quelque chose.

    Désolé pour mon niveau un peu faible ^^'

  11. #11
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par ciols Voir le message
    Les deux hash de ta dernière fonction me perturbent un peu car il n'y a pas de % devant ...
    C'est parce qu'en l'occurrence ce ne sont pas des hashes mais des références à des hashes. Ca s'utilise presque pareil : si %h est un hash, et $r une référence à un hash :
    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
    # initialisation 
    %h = ("a" => 1, "b" => 2);         $r = { "a" => 1, "b" => 2};
    # lecture d'un élément 
    $val = $h{$cle};                   $val = $r->{$cle};
    # écriture d'un élément 
    $h{$cle} = $val;                    $r->{$cle} = $val;
    # lecture de plusieurs élémens (tranchage) 
    ($v1, $v2) = @h{$c1, $c2);         ($v1, $v2) = @{$r}{$c1, $c2);
    @vals = @h{@cles);                 @vals = @{$r}{@cles};
    # écriture de plusieurs éléments (tranchage)
    @h{$c1, $c2) = ($v1, $v2);         @{$r}{$c1, $c2) = ($v1, $v2);
    @h{@cles) = @vals;                 @{$r}{@cles} = @vals;
    # listage des clés et valeurs
    @cles = keys(%h);                  @cles = keys(%$r);
    @vals = values(%h);                @vals = values(%$r);
    # copie superficielle
    %ch = %h;                          $cr = { %$r };

    Citation Envoyé par ciols Voir le message
    Je n'arrive pas à exploiter les deux hash qui sont fabriqué avec la fonction :/, j'arrive à les afficher avec print Dumper($i2n), je vois bien que ce sont des hash avec les couples clé/valeurs mais impossible d'en tirer quelque chose.
    la seconde partir de mon code montrait un exemple d'utilisation. Je le refais en moins compact. Tout d'abord dans l'appel

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Taisha:~/perl/forum $ ETCHOSTS=sample2 perl -MData::Dump -e '...' nougat choucroute tarsier.chez.moi 192.168.1.1
    • le préfixe ETCHOSTS=sample2 permet sous unix de définir une variable d'environnement pour la commande qui suit (sans polluer l'environnement global). Ici on affecte "sample2" à la variable d'environnement ETCHOSTS. On pourra accéder à cette dernière dans le script perl par $ENV{ETCHOSTS}
    • le paramètre -MData::Dump indique qu'on charge le module Data::Dump. C'est comme si on avait écrit use Data::Dump; au début du script.
    • la partie -e '...' indique qu'on va exécuter le script contenu dans la chaîne '...'
    • enfin la partie nougat choucroute tarsier.chez.moi 192.168.1.1 contient les arguments passés au script. On les retrouvera dans la variable perl prédéfinie @ARGV.


    On commence par construire les deux hashes (en fait ici deux références à des hashes)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        my ($i2n, $n2i) = build_hashes();
    On les imprime pour voir leur tête (dd est une fonction exportée par Data::Dump)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        print "\$i2n = "; dd $i2n;
        print "\$n2i = "; dd $n2i;
    ce qui produit à l'exécution
    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
    $i2n = {
      "127.0.0.1"   => ["localhost"],
      "192.168.1.1" => ["zecastor.chez.moi", "zecastor"],
      "192.168.1.2" => ["nougat.chez.moi", "nougat"],
      "192.168.1.4" => ["tarsier.chez.moi", "tarsier"],
    }
    $n2i = {
      "localhost"         => ["127.0.0.1"],
      "nougat"            => ["192.168.1.2"],
      "nougat.chez.moi"   => ["192.168.1.2"],
      "tarsier"           => ["192.168.1.4"],
      "tarsier.chez.moi"  => ["192.168.1.4"],
      "zecastor"          => ["192.168.1.1"],
      "zecastor.chez.moi" => ["192.168.1.1"],
    }
    On voit que leurs valeurs sont des références à des tableaux (à cause des crochets ouvrants et fermants [ ... ]).

    On va maintenant y accéder, en imprimant leur valeur pour les arguments passés au script. Si l'argument est de la forme x.y.z.t où x,y,z et t sont des valeurs numériques, on considère que c'est une ip et on imprime le(s) nom(s) correspondant(s) en interrogeant $i2n. Sinon on considère que c'est un nom et on imprime les ip(s) correspondante(s) en interrogeant $n2i :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        for (@ARGV) {
          print "$_ : @{ m/^\d+\.\d+\.\d+\.\d+$/ ? $i2n->{$_} : $n2i->{$_} }\n";
        }
    en décomposant :
    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
        for my $argument (@ARGV) {
          print "$argument :";
          if ($argument =~ m/^\d+\.\d+\.\d+\.\d+$/) {
            # ici l'argument est de la forme x.y.z.t où x, y, z, t sont numériques
            # on récupère le contenu du hash $i2n par $i2n->{$argument}
            # c'est une référence à un tableau. On déréférence par @{ ... }
            # et on affecte le résultat à la liste @names
            my @names = @{ $i2n->{$argument} };
            # on parcourt la liste @names pour imprimer chacune de ses valeurs
            for my $name (@names) {
              print " $name";
            }
          } else {
            # ici l'argument est un nom de machine
            # on récupère le contenu du hash $n2i par $n2i->{$argument}
            # c'est une référence à un tableau. On déréférence par @{ ... }
            # et on affecte le résultat à la liste @ips
            my @ips = @{ $n2i->{$argument} };
            # on parcourt la liste @ips pour imprimer chacune de ses valeurs
            for my $ip (@ips) {
              print " $ip";
            }
          }
          print "\n";
        }
    ce qui donne à l'exécution pour les arguments nougat choucroute tarsier.chez.moi 192.168.1.1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    nougat : 192.168.1.2
    choucroute : 
    tarsier.chez.moi : 192.168.1.4
    192.168.1.1 : zecastor.chez.moi zecastor
    Les trois premiers arguments ont été considérés comme des noms et on a imprimé la liste des ips associées. En l'occurrence il n'y en a qu'une, sauf pour choucroute qui est inconnue.
    Le dernier a été considéré comme une ip et on a imprimé la liste des noms/alias associés

    Citation Envoyé par ciols Voir le message
    Désolé pour mon niveau un peu faible ^^'
    on a tous commencé quelque part... Si tu as le temps jette peut-être un coup d'oeil là dessus

    Assure toi que tu comprends chaque instruction de la fonction build_hashes. Si ce n'est pas le cas n'hésite pas à poser des questions
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  12. #12
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    @ciols : à mon tour de poser des questions

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    sub build_hashes {
        my ($i2n, $n2i);
        local @ARGV = exists($ENV{ETCHOSTS}) ? $ENV{ETCHOSTS} : "/etc/hosts";
        while (<>) {
            next if /^\s*(#|$)/;
            my ($ip, @names) = split;
            $i2n->{$ip} = [ @names ];
            push @{$n2i->{$_}}, $ip for @names;
        }
        ($i2n, $n2i);
    }
    1. (facile) on a codé en dur le nom du fichier dans build_hashes. C'est maladroit. Comment modifier cette fonction pour qu'on lui passe le nom de fichier en paramètre ?
    2. (moins facile) imaginons qu'on veuille fusionner plusieurs fichiers hosts. Comment modifier à nouveau la fonction pour lui passer plusieurs noms de fichiers en paramètres ? A ce stade ce n'est pas grave si il y a des répétitions dans les hashes construits (e.g. localhost -> 127.0.0.1, 127.0.0.1, 127.0.0.1)
    3. (encore moins facile) Comment modifier la fonction pour qu'il n'y ait pas de répétition dans les noms associés à une ip, ou dans les ips associées à un nom ?


    P.S. : le challenge est ouvert à tous
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  13. #13
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2013
    Messages
    326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2013
    Messages : 326
    Points : 156
    Points
    156
    Par défaut
    1)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    sub build_hashes {
      my ($fichier) = @_;
      my ($i2n, $n2i);
      local @ARGV = exists($ENV{ETCHOSTS}) ? $ENV{ETCHOSTS} : $fichier;
      while (<>) {
        next if /^\s*(#|$)/;
        my ($ip, @names) = split;
        $i2n->{$ip} = [ @names ];
        push @{$n2i->{$_}}, $ip for @names;
      }
      ($i2n, $n2i);
    }
    2)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    sub build_hashes {
      my (@fichier) = @_;
      my ($i2n, $n2i);
      foreach (@fichier) {
        local @ARGV = exists($ENV{ETCHOSTS}) ? $ENV{ETCHOSTS} : $_;
        while (<>) {
          next if /^\s*(#|$)/;
          my ($ip, @names) = split;
          $i2n->{$ip} = [ @names ];
          push @{$n2i->{$_}}, $ip for @names;
        }
      }
      ($i2n, $n2i);
    }
    3) Aucune idée x)

  14. #14
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par ciols Voir le message
    1)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    sub build_hashes {
      my ($fichier) = @_;
      my ($i2n, $n2i);
      local @ARGV = exists($ENV{ETCHOSTS}) ? $ENV{ETCHOSTS} : $fichier;
      while (<>) {
        next if /^\s*(#|$)/;
        my ($ip, @names) = split;
        $i2n->{$ip} = [ @names ];
        push @{$n2i->{$_}}, $ip for @names;
      }
      ($i2n, $n2i);
    }
    pas mal, mais de cette manière tu codes quand même en dur dans la fonction l'accès à la variable d'environnement ETCHOST. L'idée serait plutôt de l'invoquer comme suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my ($i2n, $n2i) =  build_hashes($ENV{ETCHOSTS}) ? $ENV{ETCHOSTS} : $fichier);
    Citation Envoyé par ciols Voir le message
    2)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    sub build_hashes {
      my (@fichier) = @_;
      my ($i2n, $n2i);
      foreach (@fichier) {
        local @ARGV = exists($ENV{ETCHOSTS}) ? $ENV{ETCHOSTS} : $_;
        while (<>) {
          next if /^\s*(#|$)/;
          my ($ip, @names) = split;
          $i2n->{$ip} = [ @names ];
          push @{$n2i->{$_}}, $ip for @names;
        }
      }
      ($i2n, $n2i);
    }
    Idem, sauf que là le codage en dur de l'accès à la variable d'environnement ETCHOST est encore plus douteux...

    Deux remarques :
    1. La forme my (@fichier) = @_; fait ce que tu veux mais n'est pas nécessaire. Il vaudrait mieux écrire ici my @fichier = @_; Dans une affectation de liste, On utilise normalement le parenthésage à gauche du signe = pour assigner à des scalaires, ou éventuellement à une liste (qui doit alors être en dernière position car elle consomme tout ce qui reste en partie droite). Par exemple
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      Taisha:~/perl/forum $ perl -E '
      my ($x, $y, @z, $t) = (1,2,3,4,5); say "\$x = $x, \y = $y, \@z = @z, \$t = ", (defined $t ? $t :"undef")
      '
      $x = 1, y = 2, @z = 3 4 5, $t = undef
      Taisha:~/perl/forum $
    2. la boucle while (<>) { ... } itère en fait sur l'ensemble des fichiers listés dans @ARGV... Tu peux simplifier un peu ton code


    Et un problème : tu vas perdre l'alias "nougat" si tu invoques la fonction comme suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my ($i2n, $n2i) =  build_hashes("fichier1", "fichier2");
    et que fichier1 contient
    192.168.1.2    nougat.chez.moi        nougat
    et fichier2 contient
    192.168.1.2    nougat.chez.moi
    Pourquoi ? et comment corriger ?
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  15. #15
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2013
    Messages
    326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2013
    Messages : 326
    Points : 156
    Points
    156
    Par défaut
    On va perdre l'alias car dans le hash on aura deux fois le même couple clé/valeur du coup le 2ème va écraser le premier et donc on perdra l'alias ?

    Et pour éviter cela, on peut merger les deux fichiers en faisant un check des lignes pour éviter les répétitions ? Si le couple clé/valeur est déjà présent on passe à la ligne d'après. Suivant les tailles des fichiers ça peut être assez lourd mais pour le moment j'ai pas grand chose de mieux à proposer.

  16. #16
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par ciols Voir le message
    On va perdre l'alias car dans le hash on aura deux fois le même couple clé/valeur du coup le 2ème va écraser le premier et donc on perdra l'alias ?

    Et pour éviter cela, on peut merger les deux fichiers en faisant un check des lignes pour éviter les répétitions ? Si le couple clé/valeur est déjà présent on passe à la ligne d'après. Suivant les tailles des fichiers ça peut être assez lourd mais pour le moment j'ai pas grand chose de mieux à proposer.
    Un but de code vaut mieux qu'un long discours . Montre moi le code qui ferait ça (et intégrant si possible les améliorations suggérées pour les deux versions). Rappelle toi cependant qu'à ce stade, les répétitions ne sont pas graves. Ce qui serait grave serait qu'il manque un nom ou un alias
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  17. #17
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2013
    Messages
    326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2013
    Messages : 326
    Points : 156
    Points
    156
    Par défaut
    Une des technique que j'ai trouvé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    use Tie::Array::Unique;
     
    my @A = (1,2,3,4,5,6);
    my @B = (1,2,3,4,5,6,7,8,9);
    my @merged = ();
    tie @merged, 'Tie::Array::Unique', (@A,@B);
     
    print join("\n",@merged);
    Je n'ai cependant pas testé avec des fichiers texte mais je suppose que ça ne doit pas être trop différent.

  18. #18
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par ciols Voir le message
    Une des technique que j'ai trouvé : ...
    Je te demandais simplement de corriger tes versions successives de build_hashes. Tu n'as pas besoin de faire appel à des modules extérieurs. Par contre tu dois comprendre comment alimenter des hashes...

    Pour les questions de style :
    (facile) on a codé en dur le nom du fichier dans build_hashes. C'est maladroit. Comment modifier cette fonction pour qu'on lui passe le nom de fichier en paramètre ?
    la réponse est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    sub build_hashes {
        my ($filename) = @_;
        my ($i2n, $n2i);
        local @ARGV = $filename;
        while (<>) {
            ...
    }
    Ici my ($filename) = @_; initialise $filename au premier argument passé à build_hashes (les autres sont ignorés).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    local @ARGV = $filename;
    initialise @ARGV avec un seul élément, $filename. Et while (<>) { ... } va itérer sur toutes les lignes de $filename.

    (moins facile) imaginons qu'on veuille fusionner plusieurs fichiers hosts. Comment modifier à nouveau la fonction pour lui passer plusieurs noms de fichiers en paramètres ? A ce stade ce n'est pas grave si il y a des répétitions dans les hashes construits (e.g. localhost -> 127.0.0.1, 127.0.0.1, 127.0.0.1)
    Le début de la réponse est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    sub build_hashes {
        my @filenames = @_;
        my ($i2n, $n2i);
        local @ARGV = @filenames;
        while (<>) {
            ...
    }
    Ici my @filenames = @_; initialise @filenames à l'ensemble des arguments passé à build_hashes. On utilise ici le fait que while (<>) { ... } va boucler successivement sur l'ensemble des lignes de tous les fichiers figurant dans @ARGV. En réalité on pourrait même se passer de déclarer et initialiser @filenames pour écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    sub build_hashes {
        my ($i2n, $n2i);
        local @ARGV = @_;
        while (<>) {
            ...
    }

    Mais attention cela ne suffit pas. C'est pour cela que c'était labellisé moins facile . Comme je te l'indiquais, On aura de la perte si on invoque la fonction comme suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my ($i2n, $n2i) =  build_hashes("fichier1", "fichier2");
    et que fichier1 contient
    192.168.1.2    nougat.chez.moi        nougat
    et fichier2 contient
    192.168.1.2    nougat.chez.moi
    Regarde de près comment sont initialisés les éléments de $i2n et $n2i dans le corps du while...
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  19. #19
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2013
    Messages
    326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2013
    Messages : 326
    Points : 156
    Points
    156
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $i2n->{$ip} = [ @names ];
    On ne peut pas avoir deux fois la même clé dans un hash du coup lors du traitement du 2ème fichier, on va écraser la valeur de .
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    push @{$n2i->{$_}}, $ip for @names;
    Cette ligne reste un peu obscure même si je comprends le fonctionnement général. Pour chaque nom ($names) on push l'@IP dans @{$n2i->{$names}} c'est ça ?

  20. #20
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par ciols Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $i2n->{$ip} = [ @names ];
    On ne peut pas avoir deux fois la même clé dans un hash du coup lors du traitement du 2ème fichier, on va écraser la valeur de $i2n->{192.168.1.2}.
    C'est ça. Et du coup, comment transformer cette ligne de façon à ne pas écraser cette valeur mais la compléter ?

    Citation Envoyé par ciols Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    push @{$n2i->{$_}}, $ip for @names;
    Cette ligne reste un peu obscure même si je comprends le fonctionnement général. Pour chaque nom ($names) on push l'@IP dans @{$n2i->{$names}} c'est ça ?
    Hmmm. A peu près. Précisément :
    est équivalent à
    comme on n'a pas spécifié de variable de parcours pour la boucle, cette variable est par définition $_.

    $n2i->{$_} est l'élement de $n2i pour la clé $_, c'est à dire l'élément courant de la liste @names.

    @{ ... } force l'interprétation comme une liste. Donc @{$n2i->{$_}} signifie l'élement (de $n2i pour la clé $_) considéré comme une liste (ce qui est nécessaire pour pouvoir faire un push dessus).

    push @{$n2i->{$_}}, $ip for @names va donc ajouter $ip dans les listes $n2i->{$name} dont la clé $name est dans @names. Initialement aucune de ces listes n'existe. Chaque liste est créée à la première insertion.


    Note : tu peux utiliser la balise CODEINLINE plutôt que CODE pour intégrer du formatage de type code dans un texte.
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 1
    Dernier message: 23/07/2012, 13h50
  2. [XL-2007] Récupération des valeurs d'un fichier pour les copier dans un autre
    Par stelme dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 05/11/2011, 06h00
  3. valeur d'un fichier .txt dans un label
    Par jolonghorn dans le forum Agents de placement/Fenêtres
    Réponses: 4
    Dernier message: 03/12/2010, 14h59
  4. récupération des résultat de recherche google personnalisé dans un fichier
    Par bouzayani2010 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 14/04/2010, 14h34
  5. Réponses: 1
    Dernier message: 23/09/2009, 10h35

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