Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2882 connectés 

  FORUM HardWare.fr
  Programmation
  Perl

  Pb perl

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Pb perl

n°710705
loothoof
Posté le 28-04-2004 à 12:23:11  profilanswer
 

Bonjour a tous
 
je suis en stage et je doit créer un logiciel en perl.
Donc je me suis mis au perl.
Et j'ai un petit pb.
 
En effet je doit extraire des donné d'un fichier mais voila il faut que je  parcours le fichier bcp de fois.
je m'explique:
 
voici un bout du fichier a parcourir:
 
 
---------------------------------------------------------------------------------------
|               voici les mesures pour le switch switch-V1-1                     |
---------------------------------------------------------------------------------------
 
  Adresse Mac: 000xxxxxxxxx  ;  Switch: switch-V1-1  ;  Vlan: 1  ;  Port: 48  ;  Description:  lien giga<=> switch-C-1  
  Adresse Mac: 000xxxxxxxxx  ;  Switch: switch-V1-1  ;  Vlan: 1  ;  Port: 48  ;  Description:  lien giga<=> switch-C-1  
  Adresse Mac: 000xxxxxxxxx  ;  Switch: switch-V1-1  ;  Vlan: 1  ;  Port: 48  ;  Description:  lien giga<=> switch-C-1  
 
 
C un fichier qui regroupe par switch toutes les @mac et leur port de tous le parc informatique.~700 machines
 
moi il faut que fasse un petit prog qui compte le nombre de machine derriere chaque port de chaque switch.
 
Pour ce faire je creé deux boucle une pour les switch et l'autre pour les ports mais avec cette technique le tps est bcp trop long.
 
Quelqu'un aurai une idée?
 
 
merci
 

mood
Publicité
Posté le 28-04-2004 à 12:23:11  profilanswer
 

n°710733
Taz
bisounours-codeur
Posté le 28-04-2004 à 12:59:58  profilanswer
 

super titre
 
je comprens pas quand tu lis une ligne tu récupères l'adresse MAC et le port direct ..
 

n°710744
anapajari
s/travail/glanding on hfr/gs;
Posté le 28-04-2004 à 13:08:01  profilanswer
 

une bonne regex, tu récuperes tout dans un tableau, tu tries après...

n°710798
loothoof
Posté le 28-04-2004 à 13:49:35  profilanswer
 

Le truc c que je lis chaque ligne du fichier.
Une fois la ligne ds une variable je regarde le nom du switch puis le port. Si cela correspond j'incrémente un compteur.
Je repete cette opération pour toutes les ligne du fichier et pour tous ports de tous les switchs.
 
Pour etre plus explicite je vous donne un bout de code que j'execute
 
open(ECRIRE,"$chemin_rapport_ecriture/machines_par_port_de_switch" );
 
 $machine_total_reseau=0; #permet de connaitre le nombre total de machine sur le réseau
   
 foreach $switch (@switches_trouve)  
 {  
  printf ECRIRE ("Switch $switch\n" );
   
  for ($j=1 ; $j<51 ; $j++)  
  {
   printf ECRIRE ("$j " );  
  }
  printf ECRIRE (" Total " );
  printf ECRIRE (" \n" );
  $Nb_machines=0;  #permet de connaitre le nombre de machines par switch
   
  $i=1;
  for($i=1 ; $i<51 ; $i++) #pour chaque port
  {
   $Nb_machine=0;
   open(LIRE,"$chemin_rapport_lecture/rapport_tous_Switchs.txt" );
   while(<LIRE> )  
   {
    @mots=split(";",$_);
     
    if ($mots[1] eq "  Switch: $switch  " && $mots[3] eq "  Port: $i  " )
    {
     $Nb_machine++;  
    }    
   }
   close LIRE;  
   printf ECRIRE ("$Nb_machine  " );  
   $Nb_machines = $Nb_machines + $Nb_machine;  
 
  }
  printf ECRIRE (" $Nb_machines " );
  printf ECRIRE (" \n\n" );
   
  $machine_total_reseau = $machine_total_reseau + $Nb_machines;
 }
 printf ECRIRE ("Le nombre de machines sur le réseau est de $machine_total_reseau" );
 close ECRIRE;
 
 
 
voila

n°710839
anapajari
s/travail/glanding on hfr/gs;
Posté le 28-04-2004 à 14:09:05  profilanswer
 

t'as combien de lignes dans ton fichier à peu près?

n°710899
loothoof
Posté le 28-04-2004 à 14:28:37  profilanswer
 

sa varie suivant les switch qui peuvent etre connecté au réseaux. actuellement j'en ai 1000 (4switch) mais il plus tard il y aura encore 5 switch de plus.

n°710922
Aricoh
gentil mais fo po pousser
Posté le 28-04-2004 à 14:36:47  profilanswer
 

Si je comprend bien, tu as une ligne sous cette forme :

Code :
  1. Adresse Mac: 000xxxxxxxxx  ;  Switch: switch-V1-1  ;  Vlan: 1  ;  Port: 48  ;  Description:  lien giga<=> switch-C-1


 
Et tu veux récupérer "switch-V1-1" et "48" ?
 
A tester :

Code :
  1. use strict;
  2. my %liste;
  3. ... ... ...
  4. while(<MON_FICHIER> )
  5. {
  6.     if (/.+Switch: (.+) +; +Vlan.+Port: (\d+).+/)
  7.     {
  8.         ++$liste{$1}{SWITCH};
  9.         ++$liste{$1}{PORT$2};
  10.     }
  11.     else
  12.     {
  13.         print "ligne $. non topée\n";
  14.     }
  15. }


Je précise tout de suite : ma RegExp est à affiner !
 
Dans %liste, chaque switch est une clé, laquelle est un hash de hash qui contient une clé "SWITCH" qui compte le nombre de fois où une ligne a été topée concernant le-dit switch, et d'autres clés "PORTn°" où n° est le n° du port trouvé (les clés comptent le nbre de fois que le port en question est rattaché au switch).
 
Je m'explique pas super bien  :D mais pour faire un peu plus clair :
 

Code :
  1. $liste{switch-V1-1}{SWITCH} vaut 1 après avoir lu la 1ère ligne
  2. $liste{switch-V1-1}{PORT48} vaut également 1


 
Désolé si je ne suis pas assez clair :whistle:


---------------
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
n°710939
anapajari
s/travail/glanding on hfr/gs;
Posté le 28-04-2004 à 14:47:18  profilanswer
 

essaye un truc comme ça:

Code :
  1. #!/usr/bin/perl -w
  2. use strict;
  3.     my $key;
  4.     my %nbComp;
  5.     my $filename = "test.txt";
  6.     open(SOURCE, $filename) || die "Impossible d'ouvrir le fichier $filename" ;
  7.     my $content = join "", <SOURCE>;
  8.     close(SOURCE);
  9.     ### looking for each switch
  10.     my @switch = ( $content =~ /Adresse Mac:(.*?);  Switch:(.*?);  Vlan:(.*?);  Port:(.*?);/gs );
  11.     for ( my $i=0; $i<=$#switch-3; $i+=4)
  12.     {
  13.        ### building key as : Switch name|Adresse Mac|port
  14.        $key = $switch[$i+1]."|".$switch[$i]."|".$switch[$i+3];
  15.        ### removing useless space
  16.        $key =~ s/\s//g;
  17.        ### starting or increasing count of line with this key
  18.        if ( !exists $nbComp{$key}){ $nbComp{$key}=1;}
  19.         else{$nbComp{$key}++;}
  20.     }
  21. exit;


 
[edit] grillé de 11 minutes je trouve ça bogosse, en meme temps ma fenetre était passée en arriere plan :p
alors par rapport à la solution de aricoh avec la mienne tu as une hash avec le nombre de lignes trouvées pour chaque triplet switch|mac|port
[/edit]


Message édité par anapajari le 28-04-2004 à 14:50:10
n°710954
loothoof
Posté le 28-04-2004 à 14:53:01  profilanswer
 

Pouurais -tu m'expliquer cette ligne stp:
 
 if (/.+Switch: (.+) +; +Vlan.+Port: (\d+).+/);
 
 
Que vien faire le Vlan ici que signifie ces + ce .+/ et ce /. ?
Mer'ci beaucoup

n°710968
Aricoh
gentil mais fo po pousser
Posté le 28-04-2004 à 14:59:49  profilanswer
 

loothoof a écrit :

Pouurais -tu m'expliquer cette ligne stp:
 
 if (/.+Switch: (.+) +; +Vlan.+Port: (\d+).+/);
 
Que vien faire le Vlan ici que signifie ces + ce .+/ et ce /. ?
Mer'ci beaucoup

Ceci est une expression régulière.
 
Pour résumer rapidos : ".+" signifie "tout caractère autre que \n, au moins 1 fois"
 
Exemple : " +" signifie "1 ou plusieurs espaces"
 
Ce que j'ai indiqué entre parenthèses, c'est ce que mon expression régulière doit mémoriser et retourner dans $1 et $2 qui sont des variables dédiées aux expressions régulières ($1, $2, $3 et toutes celles dont tu as besoin en fait).


---------------
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
mood
Publicité
Posté le 28-04-2004 à 14:59:49  profilanswer
 

n°710972
Aricoh
gentil mais fo po pousser
Posté le 28-04-2004 à 15:01:51  profilanswer
 

oups pardon, pour "\d+", ça signifie "1 ou plusieurs nombres"


---------------
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
n°710977
loothoof
Posté le 28-04-2004 à 15:04:18  profilanswer
 

Excuse moi anapajari mais peut tu me commenter ton programme stp car je ne comprend pas grand chose.
Putain plus je découvre le perl et plus je me dit qu'il y en a  a découvrir.

n°710987
pospos
Posté le 28-04-2004 à 15:09:08  profilanswer
 

des commentaire il en a mis partout!!!

n°710989
pospos
Posté le 28-04-2004 à 15:10:19  profilanswer
 

pour les expression reguliere tappe ca dans un shell:
"perdoc perlre"

n°710993
Aricoh
gentil mais fo po pousser
Posté le 28-04-2004 à 15:12:06  profilanswer
 

Je reprend mon bout de code pour en faire un truc + simple (à toi de voir)  :)  
 

Code :
  1. while(<MON_FICHIER> )
  2.   {
  3.         s/ //g;        # je vire tous les espaces de la ligne
  4.         if (/Switch:(.+);Vlan.+Port:(\d+);/i)
  5.         {
  6.               ++$liste{$1}{SWITCH};
  7.               ++$liste{$1}{PORT$2};
  8.         }
  9.         else
  10.         {
  11.               print "ligne $. non topée\n";
  12.         }
  13.   }


Voilà. A moins que tu aies besoin de conserver chaque ligne du fichier intacte en mémoire pour un autre traitement, sinon je supprime tous les espaces de la ligne.


Message édité par Aricoh le 28-04-2004 à 15:12:35

---------------
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
n°711155
loothoof
Posté le 28-04-2004 à 16:48:13  profilanswer
 

qd j'utilise une variable du type hachage voila l'erreur:
Can't use subscript on private hash at Recup_Nb_machines_par_port.pl line 40, near "$1}"
(Did you mean $ or @ instead of %?)
 
qui connait?

n°711187
anapajari
s/travail/glanding on hfr/gs;
Posté le 28-04-2004 à 17:13:03  profilanswer
 

ça te dit pas de montrer ton code ... au moins la ligne 40 ...

n°711542
loothoof
Posté le 29-04-2004 à 10:03:26  profilanswer
 

Voici mon code  
 
 
#!/bin/perl        
use Tk;
require "mesure_parc.pl";
require "mesure.pl";
require "chemins.pl";
 
 
# Recuperation du nombre de machines par port de switch
#-------------------------------------------------------
sub Recup_Nb_machines_par_port
{  
 # récupération des switchs présent sur le réseaux
 system("ypcat hosts | grep switch > liste_switch.txt" );
 open (SNMP, "<liste_switch.txt" )  || die "Impossible d'ouvrir liste_switch.txt";
 while (<SNMP> )
 {
  # permet de ne recuperer que les noms des switch
  @champ=split(/fr/,$_);
  @champ2=split(/ /,$champ[1]);
  @champ3=split(/\t/,$champ2[1]);
  @champ4=split(/\n/,$champ3[0]);
  push(@switches_trouve,$champ4[0]);  
 }
 close SNMP;
 system("rm liste_switch.txt" );
 
 
 open(LIRE,"$chemin_rapport_lecture/rapport_tous_Switchs.txt" );
 use strict;
 
   
  while(<LIRE> )
   {
         if (/.+Switch: (.+) +; +Port: (\d+).+/)
         {
          %liste{$1}[$2]++;   #ligne ou se trouve le pb
         }
         else
         {
   print "ligne $. non topée\n";
         }
   }  
 
 printf %liste;
}
 
Le pb se trouve a la ligne 36  
et voici l'erreur:


n°711546
loothoof
Posté le 29-04-2004 à 10:06:15  profilanswer
 

Global symbol "%liste" requires explicit package name at Recup_Nb_machines_par_port.pl line 36.
Can't use subscript on hash deref at Recup_Nb_machines_par_port.pl line 36, near "$1}"
(Did you mean $ or @ instead of %?)
 
 
Si je rajoute use strict alors j'ai un pb pour toute les variables du type scalaire($)
 
qui peut m'éclaircir l'esprit?
merci.

n°711553
anapajari
s/travail/glanding on hfr/gs;
Posté le 29-04-2004 à 10:13:08  profilanswer
 

les balises cpp c'est bien!!!!
 
ensuite  

Code :
  1. ### tu as écrit
  2.   %liste{$1}[$2]++;
  3. ### Aricoh avait écrit
  4.   ++$liste{$1}{SWITCH};


Tu vois la différence?
 
par ailleurs toute cette partie ne sert plus à rien:

Code :
  1. # récupération des switchs présent sur le réseaux
  2. system("ypcat hosts | grep switch > liste_switch.txt" );
  3. open (SNMP, "<liste_switch.txt" )  || die "Impossible d'ouvrir liste_switch.txt";
  4. while (<SNMP> )
  5. {
  6.   # permet de ne recuperer que les noms des switch
  7.   @champ=split(/fr/,$_);
  8.   @champ2=split(/ /,$champ[1]);
  9.   @champ3=split(/\t/,$champ2[1]);
  10.   @champ4=split(/\n/,$champ3[0]);
  11.   push(@switches_trouve,$champ4[0]); 
  12. }
  13. close SNMP;
  14. system("rm liste_switch.txt


tu peux l'enlever.
 
enfin tu as modifié la regex et c'est n'imp:

Code :
  1. /.+Switch: (.+) +; +Port: (\d+).+/
  2. ### doit etre remplacee par celle la qui suffit amplement
  3. /Switch: (.+);.*Port: (\d+);/


 
edit: et pour le use strict, il va falloir apprendre à déclarer tes variables.


Message édité par anapajari le 29-04-2004 à 10:14:35
n°711663
loothoof
Posté le 29-04-2004 à 12:09:18  profilanswer
 

Merci les gars sa marche a présent. il me reste plus qu'a exposer mes données pour que ce soit plus convivial
merci bcp

n°711803
Aricoh
gentil mais fo po pousser
Posté le 29-04-2004 à 14:20:18  profilanswer
 

Une dernière chose, remplace :

Code :
  1. system("rm liste_switch.txt" );


par  

Code :
  1. unlink("liste_switch.txt" ) or warn("pb suppression fichier : $!\n" );


Eh oui, la commande rm a sa copine en Perl qui fait aussi la même chose, c'est la fonction unlink  :)


---------------
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
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Perl

  Pb perl

 

Sujets relatifs
[perl] Faire une page d'attente en CGIperl et linux
perl et df[PERL] supprimer un caractere d'une chaine
ssh et perl[Perl] Aide pour logique en POO
[Perl] Arrêter un programme proprement lors d'un Ctrl + C[Perl] POO et utilisation d'une method dans un print ou un shell exec
[Perl] patterns avec un object[Perl] Fichier dans un dossier ou sous-dossier
Plus de sujets relatifs à : Pb perl


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)