[PERL] Split

Split [PERL] - Perl - Programmation

Marsh Posté le 21-06-2005 à 11:11:27    

Salut voilà j'écris script Perl assez gros et j'aimerai limiter les déclarations de variables avec "my $mavariable1;". J'ai une ligne de code avec un split tel que:

Code :
  1. $li=0;
  2. while (defined($l=<FIC> ))
  3. {
  4. chomp $l;
  5. ($r1,$r2,$tablemac[$li][0],$tablemac[$li][1],$r3,$r4,$tablemac[$li][2],$tablemac[$li][3],$r5)=split(/:/,$l);
  6. $li++;
  7. }
  8. close FIC;


 
Y-a t'il une façon plus propre d'ecrire la ligne d'argument récupérant le retour du split sachant que je ne réutilise pas les variables bidons "$r1", "$r2", "$r3", "$r4" et "$r5".
 
Comme je n'utilise pas ces dernieres dans la suite du programme, l'editeur de code me mentionne : "Name main::$r1 used only once ..."
Qu'est-ce que vous proposez ???

Reply

Marsh Posté le 21-06-2005 à 11:11:27   

Reply

Marsh Posté le 21-06-2005 à 11:34:36    

Pourquoi ne pas faire quelque chose du genre :
 

Code :
  1. my @temp_result = split ':', $l;
  2. $tablemac[$li][0] = $temp_result[2];  # nom de la donnée 2
  3. $tablemac[$li][1] = $temp_result[3];  # nom de la donnée 3
  4. $tablemac[$li][2] = $temp_result[6];  # nom de la donnée 6
  5. $tablemac[$li][3] = $temp_result[7];  # nom de la donnée 7


 

Reply

Marsh Posté le 21-06-2005 à 11:52:19    

Ok ça a l'air pas mal ;) mais j'aimerai si possible rester à une instruction par tour de boucle (sans compter "chomp $l" et "$li++;" ).
 
Ceci dit je n'ai pas préciser que je voulais que le code soit optimiser en postant donc merci pour ta proposition :D
 
Si vous avez d'autre proposition plz ???

Reply

Marsh Posté le 21-06-2005 à 12:12:37    

Gouki19 a écrit :

Y-a t'il une façon plus propre d'ecrire la ligne d'argument récupérant le retour du split sachant que je ne réutilise pas les variables bidons "$r1", "$r2", "$r3", "$r4" et "$r5".


Si tu ne fais rien du contenu récupéré par tes variables $r..., tu peux faire ceci :
 

Code :
  1. (undef,undef,$tablemac[$li][0],$tablemac[$li][1],undef,undef,$tablemac[$li][2],$tablemac[$li][3],undef)=split(/:/,$l);


 
Ainsi, pas besoin de récupérer les valeurs qui ne te servent pas :)  


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO -> Google Pixel 9 PRO XL
Reply

Marsh Posté le 21-06-2005 à 12:18:38    

Aricoh a écrit :

Si tu ne fais rien du contenu récupéré par tes variables $r..., tu peux faire ceci :
 

Code :
  1. (undef,undef,$tablemac[$li][0],$tablemac[$li][1],undef,undef,$tablemac[$li][2],$tablemac[$li][3],undef)=split(/:/,$l);


 
Ainsi, pas besoin de récupérer les valeurs qui ne te servent pas :)


 
 :bounce:  
Excellent c'est exactement ce qu'il me faut, j'ai testé et ça fonctionne  :D  
Merci Aricoh    :jap:

Reply

Marsh Posté le 21-06-2005 à 12:24:01    

Gouki19 a écrit :

:bounce:  
Excellent c'est exactement ce qu'il me faut, j'ai testé et ça fonctionne  :D  
Merci Aricoh    :jap:


Mon bon coeur me perdra :D  


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO -> Google Pixel 9 PRO XL
Reply

Marsh Posté le 21-06-2005 à 12:24:55    

Mais ça reste une ligne d'un million de caractères, c'est ignoble à lire.
Même le forum il en veut pas.  [:petrus75]  
 
Si tu utilises la solution d'Aricoh, essaie au moins d'espacer :
 

Code :
  1. ( undef,
  2.   undef,
  3.   $tablemac[$li][0],
  4.   $tablemac[$li][1],
  5.   undef,
  6.   undef,
  7.   $tablemac[$li][2],
  8.   $tablemac[$li][3],
  9.   undef ) = split(/:/,$l);


Message édité par Elmoricq le 21-06-2005 à 12:40:37
Reply

Marsh Posté le 21-06-2005 à 12:40:19    

Elmoricq a écrit :

Mais ça reste une ligne d'un million de caractères, c'est ignoble à lire.
Même le forum il en veut pas.  [:petrus75]  
 
Si tu utilises la solution d'Aricoh, essaie au moins d'espacer :
 

Code :
  1. my ( undef,
  2.      undef,
  3.      $tablemac[$li][0],
  4.      $tablemac[$li][1],
  5.      undef,
  6.      undef,
  7.      $tablemac[$li][2],
  8.      $tablemac[$li][3],
  9.      undef ) = split(/:/,$l);



 
Hmmm  :whistle:  
J'ai pas bien capté ton "my" vu que le split se retrouve dans une boucle "while". Mais pour l'espacement pas de souci :D
En fait pour le moment j'ai fais comme ceci:

Code :
  1. $li=0;
  2. while (defined($l=<FIC> ))
  3. {
  4. chomp $l;
  5. (undef,undef,$tablemac[$li][0],$tablemac[$li][1],undef,undef,$tablemac[$li][2],$tablemac[$li][3],undef)=split(/:/,$l);
  6. $li++;
  7. }
  8. close FIC;


Ca fonctionne très bien :D
 
Sinon je m'égare un peu mais le but c'est de récupérer les adresses MAC d'un fichier ancien et de comparer avec un nouveau fichier pour déterminer quels sont les nouvelles adresses MAC par rapport à l'ancien fichier.  
Je sais pas si il existe des modules Perl qui font une comparaison entre 2 tableaux et renvoient tous les éléments qui apparaissent en plus...???
Si vous avez des idées ???

Reply

Marsh Posté le 21-06-2005 à 12:42:06    

Argh, j'ai retiré le "my" à l'instant, 1s avant que tu ne postes.  
Une erreur de ma part.  :sweat:  
 
Sinon la solution avec undef est bonne, mais le but de ma réponse était la mise en page. La lisibilité apporte une meilleure maintenabilité, ça permet de débusquer les erreurs plus facilement, et ça ne part pas en vrille dans un éditeur de texte plus limité. ;)

Reply

Marsh Posté le 21-06-2005 à 12:45:29    

Gouki19 a écrit :

Sinon je m'égare un peu mais le but c'est de récupérer les adresses MAC d'un fichier ancien et de comparer avec un nouveau fichier pour déterminer quels sont les nouvelles adresses MAC par rapport à l'ancien fichier.  
Je sais pas si il existe des modules Perl qui font une comparaison entre 2 tableaux et renvoient tous les éléments qui apparaissent en plus...???
Si vous avez des idées ???


Le problème en chargeant tes adresses MAC dans 2 tableaux, c'est que si la même adresse existe dans les deux tableaux MAIS pas au même emplacement du tableau, elles vont te ressortir toutes 2 comme des nouveautés :(  
 
Le must serait dans ce cas d'utiliser les hash (ou tableaux de hachage) :)  


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO -> Google Pixel 9 PRO XL
Reply

Marsh Posté le 21-06-2005 à 12:45:29   

Reply

Marsh Posté le 21-06-2005 à 12:49:46    

LOL :D
 
Ah je vois pas de souci ;)
 
Mais sinon t'aurai pas une idée pour mon deuxieme pb lol ??
 
Car j'ai pas envi de programmer une recherche dans un tableau pour controler si chaque élément d'un tableau est bien dans l'autre tableau !!! C'est lourd en temps de traitement je pense...

Reply

Marsh Posté le 21-06-2005 à 12:53:00    

Aricoh a écrit :

Le problème en chargeant tes adresses MAC dans 2 tableaux, c'est que si la même adresse existe dans les deux tableaux MAIS pas au même emplacement du tableau, elles vont te ressortir toutes 2 comme des nouveautés :(  
 
Le must serait dans ce cas d'utiliser les hash (ou tableaux de hachage) :)


 
En effet j'avais pensé à ça mais comme je maîtrise pas trop les table de hash jme suis pas lancé directement.
 
Jvais voir de ce coté là :D
 
Merci à vous mais si ya d'autres idées n'hesitez pas :D

Reply

Marsh Posté le 21-06-2005 à 12:55:03    

Gouki19 a écrit :

Mais sinon t'aurai pas une idée pour mon deuxieme pb lol ??


Comme je dis plus haut, utilise des hash au lieu de tableaux simples
 
En analysant rapidos ton truc, tu récupères 4 valeurs de chaque ligne sous la forme :
 

Code :
  1. $tablemac[ligne n][élément 1]
  2. $tablemac[ligne n][élément 2]
  3. $tablemac[ligne n][élément 3]
  4. $tablemac[ligne n][élément 4]


 
Avec un hash (déclaré %tablemac et non plus @tablemac), tu pourrais formuler ton truc sous cette forme là :
 

Code :
  1. $tablemac{ligne n}->{élément 1}
  2. $tablemac{ligne n}->{élément 2}
  3. $tablemac{ligne n}->{élément 3}
  4. $tablemac{ligne n}->{élément 4}


 
Bien entendu, il te faut 2 hash bien distincts pour pouvoir comparer tes adresses MAC. Ensuite, il te suffit de faire une petite fonction pas bien méchante à lancer 2 fois :
 
- 1ère fois, elle compare les valeurs de l'ancien fichier avec le nouveau
- 2ème fois, elle fait la même chose mais entre le nouveau et l'ancien fichier


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO -> Google Pixel 9 PRO XL
Reply

Marsh Posté le 21-06-2005 à 14:19:00    

Ok j'y vois plus clair grace à ton explication, jme suis lancé avec les table de hash et ça a l'air bien plus approprié pour ce que je veux faire :D
 
Encore merci ^^

Reply

Marsh Posté le 21-06-2005 à 14:49:00    

Aricoh a écrit :

Comme je dis plus haut, utilise des hash au lieu de tableaux simples
 
En analysant rapidos ton truc, tu récupères 4 valeurs de chaque ligne sous la forme :
 

Code :
  1. $tablemac[ligne n][élément 1]
  2. $tablemac[ligne n][élément 2]
  3. $tablemac[ligne n][élément 3]
  4. $tablemac[ligne n][élément 4]


 
Avec un hash (déclaré %tablemac et non plus @tablemac), tu pourrais formuler ton truc sous cette forme là :
 

Code :
  1. $tablemac{ligne n}->{élément 1}
  2. $tablemac{ligne n}->{élément 2}
  3. $tablemac{ligne n}->{élément 3}
  4. $tablemac{ligne n}->{élément 4}


 
Bien entendu, il te faut 2 hash bien distincts pour pouvoir comparer tes adresses MAC. Ensuite, il te suffit de faire une petite fonction pas bien méchante à lancer 2 fois :
 
- 1ère fois, elle compare les valeurs de l'ancien fichier avec le nouveau
- 2ème fois, elle fait la même chose mais entre le nouveau et l'ancien fichier


 
 
Arf par contre il faut que les mac adress soient mes clés au lieu d'un entier comptant le nombre de ligne...
 
J'ai fais ceci mais j'ai des doutes car j'arrive pas à afficher les bonnes valeurs...

Code :
  1. while (defined($l=<FIC> ))
  2. {
  3. chomp $l;
  4. (undef,undef,$oldmac,$tablemac{$oldmac}->{1},undef,undef,$tablemac{$oldmac}->{2},$tablemac{$oldmac}->{3},undef)=split(/:/,$l);
  5. }
  6. close FIC;
  7. foreach my $v (values(%tablemac))
  8. {
  9.    print "Valeur=$v<br>";
  10.    $t++;
  11. }


Je sais pas comment gérer les tables de hash à plusieurs dimensions... :pt1cable:

Reply

Marsh Posté le 21-06-2005 à 15:34:00    

Gouki19 a écrit :

Arf par contre il faut que les mac adress soient mes clés au lieu d'un entier comptant le nombre de ligne...
 
J'ai fais ceci mais j'ai des doutes car j'arrive pas à afficher les bonnes valeurs...
 
Je sais pas comment gérer les tables de hash à plusieurs dimensions... :pt1cable:


 
Je n'ai pas bien compris ce que tu cherchais à faire exactement, mais j'ai le sentiment qu'un hash de tableaux devrait te convenir (en admettant que je ne me trompe pas sur tes intentions).
 
Exemple :
 

Code :
  1. # stockage
  2. my %hashtable;
  3. while ( @table = ...plein de données... )
  4. {
  5.    my $key = ...chercher la clef qui va bien... ;
  6.    $hashtable{$key} = \@table;
  7. }
  8. # pour retrouver les valeurs :
  9. foreach my $key ( keys %hashtable )
  10. {
  11.    # reference du tableau, on peut dereferencer avec @{ ... }
  12.    my $reftable = $hashtable{$key};
  13.    # exemple, avec parcours du tableau
  14.    foreach my $data ( @{ $reftable } )
  15.    {
  16.       ...faire ce qu'on veut avec $data...
  17.    }
  18.    # on peut aussi acceder à une ligne du tableau directement
  19.    # prenons la seconde ligne, comme ça, au hasard :
  20.    my $data = $hashtable{$key}->[1];
  21. }


 
On peut évidemment adapter ce principe pour créer des hash de hash, si jamais c'est ça qu'il te faut. ;)


Message édité par Elmoricq le 21-06-2005 à 15:35:11
Reply

Marsh Posté le 21-06-2005 à 16:56:05    

Ok je vais étudier ça pour voir si ça peut me convenir sinon j'essaierai d'etre plus clair sur mes intentions lors de mon prochain post ;)

Reply

Marsh Posté le 22-06-2005 à 15:54:47    

Re finalement c'est bon j'ai pu m'en sortir et faire ce que je voulais :D
 
Jvous remercie à tous pour votre aide ;)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed