[Résolu] Trie adresse IP

Trie adresse IP [Résolu] - Perl - Programmation

Marsh Posté le 29-06-2015 à 11:37:58    

Bonjour la communauté !  
 
Je demande votre aide car je n'arrive pas à faire un tri de mes adresses IPs qui s'affichent à l'écran. Mon script pour sortir les adresses IP de mon fichier fonctionne mais quand je veux les trier avant de les affichers, je n'y arrive pas, il ne me les trie pas ...
 
Voici mon code :
 

Code :
  1. my $formatted_output;
  2. my @ip;
  3. my @result;
  4.     if ($end && $end < $now) {
  5.         # on ne veut pas les adresses expirées
  6.     }
  7.     else {
  8.         $formatted_output =
  9.             sprintf "\033[32m%-15s : %-26s "              . "  %19s  "        ."%9s "        ."%24s  --  "             . "%24s\033[0m\n",
  10.                              $ip,    $h{'client-hostname'}, "($h{'hardware'})", $h{'binding'}, scalar(localtime $start), scalar(localtime $end);
  11.     }
  12. sub packed {
  13.    pack('C4', split(/\./, $a)) cmp pack('C4', split(/\./, $b));
  14. }
  15. @result = sort packed $formatted_output;
  16.     next if $seen{$formatted_output};
  17.     $seen{$formatted_output}++;
  18.     print @result;
  19. }


 
Donc j'ai choisi de faire une routine packed mais si vous avez une autre solution je suis preneur ! :)
 
P.S : Je suis débutant en Perl depuis peu donc il se peut qu'il y est des erreurs.


Message édité par romyx1 le 30-06-2015 à 09:46:06
Reply

Marsh Posté le 29-06-2015 à 11:37:58   

Reply

Marsh Posté le 29-06-2015 à 13:11:18    

Donne un exemple compilable/exécutable et précise comment tu veux trier tes adresses (avec des exemples).

Reply

Marsh Posté le 29-06-2015 à 13:42:17    

C'est peut-être moi (débutant) qui ignore un truc mais ceci

Code :
  1. @result = sort packed $formatted_output;


me paraît douteux. $formatted_output c'est un seul string, pas grand chose à trier donc. Ca serait pas plutôt sort packed @ip ou quelque chose comme ça?

Reply

Marsh Posté le 29-06-2015 à 14:29:42    

Alors, j'ai un fichier venant de dhcpd.leases.
J'ouvre le fichier je le lis et je stock les adresses ip qui sont encore valide et les affiches ensuite.
Maintenant j'aimerai que les IPs afficher soit trier =).
 
J'ai essayé avec @ip en disant que mon @ip = $ip ou @ip = $_. Soit m'affiche les résultats mais non trier. Après je ne suis pas très bon en perl et j'ai encore du mal à tout comprendre :s.
 
Mes adresse je veux les trier par plage :
 
ex :  
 
172.17.112.0
172.17.111.1
172.17.110.0 ...
 
En ce moment j'ai les IP mais non trier.

Reply

Marsh Posté le 29-06-2015 à 14:36:56    

Citation :

J'ai essayé avec @ip en disant que mon @ip = $ip ou @ip = $_.


 :??:
sort ça prends un array et ça ressort un array, soit @result = sort @donnees.

 

Si j'ai bien compris ce que tu veux:

Code :
  1. use strict;
  2. use warnings FATAL => 'all';
  3.  
  4. my @addr=qw(172.17.110.0 172.17.110.1 172.17.111.0 172.16.255.243 172.16.255.244 172.17.112.0 172.17.111.1 );
  5.  
  6. sub packed {
  7.   pack('C4', split(/\./, $a)) cmp pack('C4', split(/\./, $b));
  8. }
  9.  
  10. my @result1 = sort packed @addr; #ordre croissant
  11. my @result2 = reverse sort @addr; #ordre décroissant
  12.  
  13. print join("\n",@result1);
  14.  
  15. print "\n\n";
  16.  
  17. print join("\n",@result2);
 

A toi d'inclure ça dans ton script... En fait ton sub packed est bon, c'est juste l'appel de sort qui ne va pas.

 


edit: Si c'est pas clair, si il y a un autre soucis, ... je répète: donne un code compilable/exécutable, voire le script complet. Le script de ton premier post je ne peux pas l'exécuter parce qu'il manque des choses.


Message édité par rat de combat le 29-06-2015 à 14:39:30
Reply

Marsh Posté le 29-06-2015 à 14:40:31    

Ouais j'avais déjà vu un truc dans le genre mais dans my @addr = qw, je mets quoi dedans car j'ai pleins d'ip qui vient et ça peut être aléatoire.

Reply

Marsh Posté le 29-06-2015 à 14:44:30    

Désolé, je crois que tu n'as pas compris. Le qw() tu en as pas besoin, toi tu vas lire tes adresses dans ton fichier ou ailleurs. Moi par contre j'ai utilisé le qw() pour insérer des adresses ip "bidons" pour avoir un script complet que je peux tester. J'aurais pu faire autrement mais qw() c'est le moins long à tapper...

Reply

Marsh Posté le 29-06-2015 à 14:48:29    

Voilà le code complet :
 

Code :
  1. #!/usr/bin/perl
  2.  
  3. my $VERSION=0.03;
  4.  
  5. my $leases_file = "/home/romain_bureau/Documents/synchro_docs/Test_DHCP/dhcpd.leases";
  6.  
  7. use strict;
  8. use Date::Parse;
  9. use Term::ANSIColor;
  10.  
  11. my $now = time;
  12. my %seen;       # leases file has dupes (because logging failover stuff?). This hash will get rid of them.
  13.  
  14. open(L, $leases_file) or die "Cant open $leases_file : $!\n";
  15. undef $/;
  16. my @records = split /^lease\s+([\d\.]+)\s*\{/m, <L>;
  17. shift @records; # remove stuff before first "lease" block
  18.  
  19. ## process 2 array elements at a time: ip and data
  20.  
  21. # affichage du header
  22.  
  23. my $header=("\t\@IP\t||\tHOST NAME\t||\t\tMAC\t\t||\t\tSTATE\t\t||\t   DATE END\n" );
  24. print color 'bold';
  25. print "====================================================================================================================================\n";
  26. print $header;
  27. print "====================================================================================================================================\n\n";
  28. print color 'reset';
  29.  
  30. # début processus
  31.  
  32. foreach my $i (0 .. $#records) {
  33.    next if $i % 2;
  34.    my ($ip, $_) = @records[$i, $i+1];
  35.  
  36.    s/^\n+//;     # && warn "leading spaces removed\n";
  37.    s/[\s\}]+$//; # && warn "trailing junk removed\n";
  38.  
  39.    my ($s) = /^\s* starts \s+ \d+ \s+ (.*?);/xm;
  40.    my ($e) = /^\s* ends   \s+ \d+ \s+ (.*?);/xm;
  41.  
  42.    my $start = str2time($s);
  43.    my $end   = str2time($e);
  44.  
  45.    my %h; # to hold values we want
  46.  
  47.    foreach my $rx ('binding', 'hardware', 'client-hostname') {
  48.        my ($val) = /^\s*$rx.*?(\S+);/sm;
  49.        $h{$rx} = $val;
  50.    }
  51.  
  52.    my $formatted_output;
  53.  
  54.    if ($end && $end < $now) {
  55.        # we don't want the expired ip address
  56.    }
  57.    else {
  58.        $formatted_output =
  59.            sprintf "\033[32m%-15s : %-26s "              . "  %19s  "        ."%9s "        ."%24s  --  "             . "%24s\033[0m\n",
  60.                             $ip,    $h{'client-hostname'}, "($h{'hardware'})", $h{'binding'}, scalar(localtime $start), scalar(localtime $end);
  61.    }
  62.    next if $seen{$formatted_output};
  63.    $seen{$formatted_output}++;
  64.    print $formatted_output;
  65. }

Reply

Marsh Posté le 29-06-2015 à 14:50:41    

Et le fichier dhcpd.leases ça ressemble à quoi? J'y connais rien moi en réseaux...

Reply

Marsh Posté le 29-06-2015 à 14:53:11    

Pleins de fois des trucs comme ça avec bien sur les ip qui changent etc ...
 
lease 172.17.97.241 {
 starts 5 2015/04/17 14:42:21 UTC;
 ends 6 2015/04/18 02:42:21 UTC;
 hardware ethernet 00:08:5d:44:64:e2;
 uid 01:00:08:5d:44:64:e2;
 client-hostname "6867i00085D4464E2";
}

Reply

Marsh Posté le 29-06-2015 à 14:53:11   

Reply

Marsh Posté le 29-06-2015 à 15:04:32    

Ok. Ton script tu l'as fait toi-même ou pris sur internet en entier ou pris sur internet par morceaux? Parce que là j'avoue que j'ai du mal à m'y retrouver... Bon, je vais voir ce que je peux faire.

Reply

Marsh Posté le 29-06-2015 à 15:08:49    

La plupart fait par moi, quelques trucs prit sur le net, j'ai mit 3 semaines à faire ça :pt1cable:  
Sans le tri des IP, mon script marche très bien, il fait exactement ce que je lui demande :)

Reply

Marsh Posté le 29-06-2015 à 15:12:38    

Ok. Le truc c'est que (à mon avis) pour mettre un tri des adresses faut réorganiser le script autrement, il suffit pas de rajouter une ligne ou deux. En effet faut avoir un tableau de tout les adresses qu'on classe d'abord et ensuite on regarde pour l'affichage. Sauf que pour chaque adresse il y a d'autres infos qu'il faut mémoriser en même temps. C'est tout à fait faisable mais faut modifier le truc. Si tu me laisses un peu de temps je veux bien essayer de bricoler quelque chose (même si il y a des chances que gilou soit plus rapide...  ;) ).

 

EDIT: Par contre je veux bien un exemple réel de fichier dhcp.leases, histoire d'être vraiment sûr du format.


Message édité par rat de combat le 29-06-2015 à 15:13:59
Reply

Marsh Posté le 29-06-2015 à 15:18:24    

Okay bah merci car là je suis un perdu ... Je peux attendre oui =).
L'exemple que je t'ai donné est un vrai ;). Ca ressemble exactement à ça =). Et tu as X adresses avec ce genre d'exemple. C'est un fichier .leases qui s'ouvre comme un fichier .txt ;)

Reply

Marsh Posté le 29-06-2015 à 15:32:01    

ligne 47: binding il sort d'où, j'en vois pas dans ton exemple de fichier dhcpd.leases... Et hardware c'est hardware ethernet je suppose?

Reply

Marsh Posté le 29-06-2015 à 15:46:36    

Hardware c'est harware ethernet oui (adresse mac quoi).
Binding autant pour moi c'était des tests et j'ai oublié de le retirer ;). Donc tu  peux retirer binding ligne 47 et ligne 59 et 60.


Message édité par romyx1 le 29-06-2015 à 15:47:14
Reply

Marsh Posté le 29-06-2015 à 15:57:19    

Voici un truc fait à la va-vite mais qui fonctionne bien en tout cas avec les données que j'ai. À tester avant mise en prod...
À toi de faire la mise en page que tu veux (et que je ne connais pas) avec sprintf() et puis le print "HEADER.
Faut aussi rajouter les couleurs, chez moi sous Windows ça ne marche pas et j'y connais rien.

 

Le code me paraît assez explicite, sinon n'hésite pas à poser des questions. On peut certainement faire autrement/plus élégant mais moi aussi je suis débutant et puis TMTOWTDI. ;)

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings FATAL => 'all';
  4. no warnings 'experimental';
  5. use Date::Parse;
  6. use autodie;
  7.  
  8. #use Data::Dumper; #debug
  9.  
  10. my $leases_file='dhcpd.leases';
  11.  
  12. my $now=time;
  13.  
  14. open(L, $leases_file);
  15.  
  16. my ($ip, $start, $end, $hw_eth, $uid, $client_hostname);
  17.  
  18. my @res;
  19.  
  20. while(<L> )
  21. {
  22.     if(/^lease\s+([\d\.]+)\s*{/)
  23.     {
  24.         $ip=$1;
  25.     }
  26.     elsif(/^\s* starts \s+ \d+ \s+ (.*?);/x)
  27.     {
  28.         $start=str2time($1);
  29.     }
  30.     elsif(/^\s* ends \s+ \d+ \s+ (.*?);/x)
  31.     {
  32.         $end=str2time($1);
  33.     }
  34.     elsif(/^\s* hardware\sethernet \s+ (.*?);/x)
  35.     {
  36.         $hw_eth=$1;
  37.     }
  38.     elsif(/^\s* uid \s+ (.*?);/x)
  39.     {
  40.         $uid=$1;
  41.     }
  42.     elsif(/^\s* client-hostname \s+ (.*?);/x)
  43.     {
  44.         $client_hostname=$1;
  45.     }
  46.     elsif(/^\s*}\s*$/) #fin d'un bloc --> traitement
  47.     {
  48.         if($end > $now) #encore valide?
  49.         {
  50.             my  $formatted_output=sprintf "%s <-> %s <-> %s <-> %s <-> %s",
  51. $ip, $client_hostname, "($hw_eth)", scalar(localtime $start), scalar(localtime $end); #FORMAT À PRÉCISER
  52.             
  53.             if(!($formatted_output ~~ @res)) #pas encore dans le tableau? outil expérimental, à remplacer??
  54.             {
  55.                 push @res, $formatted_output; #alors rajouter
  56.             }
  57.         }
  58.     }
  59. }
  60.  
  61. close(L);
  62.  
  63. sub sortsub
  64. {
  65.     $a=~/^([\d\.]+?)\s/; my $ip1=$1; #sortir adresse ip
  66.     $b=~/^([\d\.]+?)\s/; my $ip2=$1; #de même
  67.     
  68.     return pack('C4', split(/\./, $ip1)) cmp pack('C4', split(/\./, $ip2));
  69. }
  70.  
  71. @res=sort sortsub @res; #trier selon adresse ip
  72.  
  73. print "HEADER A FAIRE\n";
  74.  
  75. print "$_\n", foreach (@res); #affichage
 

edit: J'ai repris les regex de ton code, possible qu'il y ait des choses améliorables, j'ai pas analysé en détail.


Message édité par rat de combat le 29-06-2015 à 16:02:07
Reply

Marsh Posté le 29-06-2015 à 16:01:38    

Le fichier dhcpd.leases que j'avais bricolé et utilisé pour mes tests: 2 entrées encore valides (changé le 2015 en 2016...) et deux autres non.
 

Code :
  1. lease 172.17.97.241 {
  2. starts 5 2015/04/17 14:42:21 UTC;
  3. ends 6 2015/04/18 02:42:21 UTC;
  4. hardware ethernet 00:08:5d:44:64:e2;
  5. uid 01:00:08:5d:44:64:e2;
  6. client-hostname "6867i00085D4464E2";
  7. }
  8. lease 172.17.97.255 {
  9. starts 5 2015/04/17 14:42:21 UTC;
  10. ends 6 2016/04/18 02:42:21 UTC;
  11. hardware ethernet 00:08:5d:44:64:e2;
  12. uid 01:00:08:5d:44:64:e2;
  13. client-hostname "6867i00085D4464E2";
  14. }
  15. lease 172.17.97.241 {
  16. starts 5 2015/04/17 14:42:21 UTC;
  17. ends 6 2015/04/18 02:42:21 UTC;
  18. hardware ethernet 00:08:5d:44:64:e2;
  19. uid 01:00:08:5d:44:64:e2;
  20. client-hostname "6867i00085D4464E2";
  21. }
  22. lease 172.17.97.1 {
  23. starts 5 2015/04/17 14:42:21 UTC;
  24. ends 6 2016/04/18 02:42:21 UTC;
  25. hardware ethernet 00:08:5d:44:64:e2;
  26. uid 01:00:08:5d:44:64:e2;
  27. client-hostname "6867i00085D4464E2";
  28. }

Reply

Marsh Posté le 29-06-2015 à 16:09:10    

Merci beaucoup ! Mais je viens de le tester et j'ai une erreur à la ligne 67 avec $ip1 :
"Use of uninitialized value $ip1 in split"

Message cité 1 fois
Message édité par romyx1 le 29-06-2015 à 16:09:43
Reply

Marsh Posté le 29-06-2015 à 16:11:51    

A oui, pour le truc avec expérimental, c'est le "~~" = "smartmatch operator" dont je parle. Au pire on modifie
 

Code :
  1. ...
  2. if(!is_in_list($formatted_output, \@res))
  3. ...
  4.  
  5. sub is_in_list
  6. {
  7.     my ($el, $ref)=(shift, shift);
  8.     foreach (@$ref)
  9.     {
  10.         if($_ eq $el)
  11.         {
  12.             return 1;
  13.         }
  14.     }
  15.     return 0;
  16. }


ou semblable...

Reply

Marsh Posté le 29-06-2015 à 16:13:32    

romyx1 a écrit :

Merci beaucoup ! Mais je viens de le tester et j'ai une erreur à la ligne 67 avec $ip1 :
"Use of uninitialized value $ip1 in split"


Ca c'est ton fichier qui n'est pas bon ou pas comme je pensais, fait donc voir...

 

Tu peux aussi remettre un print Dumper(@res); et poster le résultat avant le truc avec le sort.

 

edit: Dumper doit sortir

Code :
  1. $VAR1 = '172.17.97.255 <-> "6867i00085D4464E2" <-> (00:08:5d:44:64:e2) <-> Fri Apr 17 16:42:21 2015 <-> Mon Apr 18 04:42:21 2016';
  2. $VAR2 = '172.17.97.1 <-> "6867i00085D4464E2" <-> (00:08:5d:44:64:e2) <-> Fri Apr 17 16:42:21 2015 <-> Mon Apr 18 04:42:21 2016';


avec mon fichier exemple.


Message édité par rat de combat le 29-06-2015 à 16:14:54
Reply

Marsh Posté le 29-06-2015 à 16:16:15    

Mon fichier ressemble exactement à ce que tu as mit haha.  
 
Voici 5 exemples qui se suivent :
 
lease 172.17.99.167 {
 starts 1 2015/06/15 12:42:03 UTC;
 ends 2 2015/06/16 00:42:03 UTC;
 hardware ethernet 00:08:5d:43:48:8b;
 uid 01:00:08:5d:43:48:8b;
 client-hostname "6867i00085D43488B";
}
lease 172.17.110.46 {
 starts 1 2015/06/15 12:44:29 UTC;
 ends 2 2015/06/16 00:44:29 UTC;
 hardware ethernet 00:08:5d:44:61:77;
 uid 01:00:08:5d:44:61:77;
 client-hostname "6867i00085D446177";
}
lease 172.17.98.134 {
 starts 1 2015/06/15 12:45:51 UTC;
 ends 2 2015/06/16 00:45:51 UTC;
 hardware ethernet 00:08:5d:44:65:53;
 uid 01:00:08:5d:44:65:53;
 client-hostname "6867i00085D446553";
}
lease 172.17.97.2 {
 starts 1 2015/06/15 12:49:09 UTC;
 ends 2 2015/06/16 00:49:09 UTC;
 hardware ethernet 00:08:5d:44:64:e8;
 uid 01:00:08:5d:44:64:e8;
 client-hostname "6867i00085D4464E8";
}
lease 172.17.99.176 {
 starts 1 2015/06/15 12:50:51 UTC;
 ends 2 2015/06/16 00:50:51 UTC;
 hardware ethernet 00:08:5d:44:6b:6e;
 uid 01:00:08:5d:44:6b:6e;
 client-hostname "6867i00085D446B6E";
}

Reply

Marsh Posté le 29-06-2015 à 16:18:55    

romyx1 a écrit :

Voici 5 exemples qui se suivent :


Chez moi ça marche très bien, il n'y a simplement rien dans le résultat car les entrées sont déjà invalides (ends au mois de juin).

 

--> :??:

 

Le Dumper ça donne quoi?

 

EDIT: gestion d'erreurs dans le sortsub:

Code :
  1. sub sortsub
  2. {
  3.     my ($ip1, $ip2);
  4.     if($a=~/^([\d\.]+?)\s/)
  5.     {
  6.         $ip1=$1; #sortir adresse ip
  7.     }
  8.     else
  9.     {
  10.         die "sortsub: can't find ip in $a";
  11.     }
  12.     if($b=~/^([\d\.]+?)\s/)
  13.     {
  14.         $ip2=$1; #sortir adresse ip
  15.     }
  16.     else
  17.     {
  18.         die "sortsub: can't find ip in $b";
  19.     }
  20.     
  21.     return pack('C4', split(/\./, $ip1)) cmp pack('C4', split(/\./, $ip2));
  22. }


Message édité par rat de combat le 29-06-2015 à 16:22:05
Reply

Marsh Posté le 29-06-2015 à 16:23:09    

J'ai 5 ip que j'ai changé jusqu'au mois d'aout ;).
 
Le dumper si je mets :
 
print Dumper(@res);
 
Ca me met une erreur aussi haha

Reply

Marsh Posté le 29-06-2015 à 16:25:17    

Avec la gestion d'erreur du sort sub j'ai ça dans mon terminal ubuntu
 
sortsub: can't find ip in 172.17.112.1    <-> "6867i00085D44D88E"        <->  (00:08:5d:44:d8:8e) <-> Wed May 13 10:27:07 2015  --  <-> Thu Aug 13 22:27:07 2015

Reply

Marsh Posté le 29-06-2015 à 16:26:03    

Citation :

haha


 :??:  
 
L'erreur c'est "Undefined subroutine"? Evidemment faut remettre le use Data::Dumper;...

Reply

Marsh Posté le 29-06-2015 à 16:28:04    

Okay désolé ...
Effectivement j'ai bien les @IP qui s'affichent avec le Dumper ;) :
 

Code :
  1. $VAR1 = '172.17.112.1    <-> "6867i00085D44D88E"        <->  (00:08:5d:44:d8:8e) <-> Wed May 13 10:27:07 2015  --  <-> Thu Aug 13 22:27:07 2015
  2. ';
  3. $VAR2 = '172.17.111.169  <-> "6867i00085D4463AD"        <->  (00:08:5d:44:63:ad) <-> Mon Jun 15 14:29:18 2015  --  <-> Sun Aug 16 02:29:18 2015
  4. ';
  5. $VAR3 = '172.17.111.18   <-> "6867i00085D446AD8"        <->  (00:08:5d:44:6a:d8) <-> Mon Jun 15 14:02:23 2015  --  <-> Sun Aug 16 02:02:23 2015
  6. ';
  7. $VAR4 = '172.17.111.110  <-> "6867i00085D4461D5"        <->  (00:08:5d:44:61:d5) <-> Mon Jun 15 13:37:44 2015  --  <-> Sun Aug 16 01:37:44 2015
  8. ';
  9. $VAR5 = '172.17.110.44   <-> "6867i00085D4461D3"        <->  (00:08:5d:44:61:d3) <-> Mon Jun 15 08:52:38 2015  --  <-> Sat Aug 15 20:52:38 2015
  10. ';
  11. $VAR6 = '172.17.97.235   <-> "6867i00085D446C2A"        <->  (00:08:5d:44:6c:2a) <-> Wed Apr 15 17:06:31 2015  --  <-> Sun Aug 16 05:06:31 2015
  12. ';
  13. $VAR7 = '172.17.110.44   <-> "6867i00085D4461D3"        <->  (00:08:5d:44:61:d3) <-> Mon Jun 15 14:52:43 2015  --  <-> Sun Aug 16 02:52:43 2015
  14. ';


Message édité par romyx1 le 29-06-2015 à 16:28:17
Reply

Marsh Posté le 29-06-2015 à 16:31:52    

Là je ne comprends pas... Le regex dans le sort fonctionne bien ici...
Remets donc le script complet et exactement le fichier dhcpd que tu utilises, je testerai chez moi.

 

edit: Au pif, si tu modifies les deux(!) regex (dans sortsub) ainsi

Code :
  1. /^\s*([\d\.]+?)\s/

ça donne quoi?


Message édité par rat de combat le 29-06-2015 à 16:33:28
Reply

Marsh Posté le 29-06-2015 à 16:39:54    

Tu as déjà essayé pour mettre des couleurs? Parce que dans ce cas il y a peut-être des trucs en début de $a et $b et du coup le regex ne marche plus. Par contre dans ton Dumper je ne vois rien, alors je sais pas... Comme je disais, sois très précis en donnant exactement ce que tu utilises actuellement.

Reply

Marsh Posté le 29-06-2015 à 16:46:18    

Ok c'était bien les couleurs merci rat de combat. Mais j'aimerai y rajouter des couleurs maintenant :sweat: :sarcastic:

Reply

Marsh Posté le 29-06-2015 à 16:48:14    

Alors faut simplement modifier le regex dans sortsub.

 

Voyons,

Code :
  1. /([\d\.]+?)\s/

(tu notera l'absence du ^) semble fonctionner. Sinon faut me dire ce que tu as rajouté exactement pour les couleurs.


Message édité par rat de combat le 29-06-2015 à 16:48:42
Reply

Marsh Posté le 29-06-2015 à 16:57:24    

Code :
  1. sprintf "\033[32m%-15s : %-26s "              . "  %19s  "                ."%24s  --  "             . "%24s\033[0m\n",


 
Voila sur la ligne ce que j'ai rajouté pour que ça apparaisse en vert ;)

Reply

Marsh Posté le 29-06-2015 à 16:58:49    

ok, regarde le regex de mon message Posté le 29-06-2015 à 16:48:14.

 

Je dois m'absenter là, désolé. Bon courage.


Message édité par rat de combat le 29-06-2015 à 16:59:33
Reply

Marsh Posté le 29-06-2015 à 17:01:27    

Okay merci beaucoup en tout cas !!! Tu m'as été d'une précieuse aide et j'ai bien compris ton script grâce au '#' ;)

Reply

Marsh Posté le 29-06-2015 à 17:04:19    

Okay j'ai trouvé ! Merci beaucoup en tout cas !! Je reviendrai vers toi si j'ai d'autre question sur ce script car j'aimerai peut être rajouter un compteur pour compter (*sans déconner*) le nombre d'ip active trouvé ;)

Reply

Marsh Posté le 29-06-2015 à 18:10:12    

Pour ton compteur suffit de regarder le nombre d'entrées dans @res:

Code :
  1. print scalar(@res)," adresses actives!\n";


Reply

Marsh Posté le 29-06-2015 à 19:55:49    

romyx1, tu es sur de ton format de dhcpd.leases?
Parce que les dates y sont toujours au format UTC, et dans toutes les descriptions de dhcpd.leases que j'ai trouvé, elles ne sont jamais accompagnées de UTC à la fin avant le ; (dans starts ou ends par exemple).
J'ai testé ton exemple sur un module Perl de CPAN qui parse les dhcpd.leases et les dates avec UTC ont été considérées comme incorrectes.

Citation :

THE LEASE DECLARATION
 
       lease ip-address { statements... }
 
       Each lease declaration includes the single IP  address  that  has  been
       leased  to  the  client.    The statements within the braces define the
       duration of the lease and to whom it is assigned.
 
       starts date;
       ends date;
       tstp date;
       tsfp date;
 
       The start and end time of a lease are recorded  using  the  starts  and
       ends  statements.    The  tstp  statement  is specified if the failover
       protocol is being used, and indicates what time the peer has been  told
       the  lease  expires.    The  tsfp  statement  is  also specified if the
       failover protocol is being used, and indicates the  lease  expiry  time
       that the peer has acknowledged.   The date is specified as follows:
 
       weekday year/month/day hour:minute:second

 
       The weekday is present to make it easy for a human to tell when a lease
       expires - it’s specified as a number from zero to six, with zero  being
       Sunday.   The  day  of week is ignored on input.  The year is specified
       with the century, so it should generally  be  four  digits  except  for
       really long leases.  The month is specified as a number starting with 1
       for January.  The day of the month is likewise specified starting  with
       1.   The hour is a number between 0 and 23, the minute a number between
       0 and 59, and the second also a number between 0 and 59.
 
       Lease times are specified in Universal Coordinated Time (UTC),  not  in
       the  local time zone.  There is probably nowhere in the world where the
       times recorded on a lease are always the same as wall clock times.   On
       most  unix  machines, you can display the current time in UTC by typing
       date -u.
 
       If a lease will never expire, date is never instead of an actual  date.


 
A+,


Message édité par gilou le 29-06-2015 à 19:59:38

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 29-06-2015 à 22:14:26    

Un exemple de solution qui peut marcher au vu de vôtre jeu de données, que je donne comme exemple de méthode permettant de traiter des suites de records de structure fixe:

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use autodie;
  5. use Date::Parse;
  6. use Term::ANSIColor;
  7. our $VERSION = 0.03;
  8.  
  9. my $DATE = '\d{4}\/\d{2}\/\d{2}\s\d{2}:\d{2}:\d{2}';
  10. my $IPV4  = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
  11. my $MAC  = '[0-9A-Fa-f]{2}(?::[0-9A-Fa-f]{2}){5}';
  12. my $ETMAC  = '01(?::[0-9A-Fa-f]{2}){6}';  # 01 for ethernet followed by MAC address
  13.  
  14. my $leases_file = 'dhcpd.leases';
  15. open(my $fh, "<", $leases_file);
  16. undef $/;
  17. $_ = <$fh>;
  18. close($fh);
  19.  
  20. my $now = time;
  21. my %leases;
  22. # comment on parse un ensemble répétitif de structure fixe (ie un record)
  23. while (m{
  24. ^lease \s+ ($IPV4) \s+ \{ \s* \n
  25. \s* starts \s+ \d \s ($DATE) \s UTC ; \s* \n
  26. \s* ends   \s+ \d \s ($DATE) \s UTC ; \s* \n
  27. \s* hardware \s+ ethernet \s+ ($MAC); \s* \n
  28. \s* uid \s+ ($ETMAC); \s* \n
  29. \s* client-hostname \s+ "([^\"]+)"; \s* \n
  30. \s* \} \s* \n
  31. }xmg) {
  32.  my $start = str2time($2);
  33.  my $end = str2time($3);
  34.  # commenté pour mon jeu de tests, à décommenter avec de vraies données
  35.  # next if ($end && $end < $now);
  36.  # clé unique pour virer les doublons, à la construction du hash
  37.  my $key = $1.$start.$end.$4.$5.$6;
  38.  $leases{$key}{"ip"} = $1;
  39.  $leases{$key}{"start"} = scalar(localtime $start);
  40.  $leases{$key}{"end"} = scalar(localtime $end);
  41.  $leases{$key}{"hardware"} = $4;
  42.  $leases{$key}{"binding"} = $5;
  43.  $leases{$key}{"hostname"} = $6;
  44. }
  45.  
  46. # on parcourt le hash en triant selon les IPs
  47. foreach ( sort {my @a = split /\./, $leases{$a}{"ip"}; my @b = split /\./, $leases{$b}{"ip"};
  48.         $a[0] <=> $b[0] or $a[1] <=> $b[1] or $a[2] <=> $b[2] or $a[3] <=> $b[3];} (keys %leases)) {
  49.  print $leases{$_}{"ip"}, "\n"; # a remplacer par un truc plus complexe dans votre code
  50. }


Un petit coup de Data::Dumper sur %leases vous permettra de visualiser la structure obtenue après parsing.
A adapter selon vos données.
 
A+,


Message édité par gilou le 29-06-2015 à 22:25:20

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 30-06-2015 à 09:14:13    

Merci gilou et rat de combat, le compteur j'avais réussi aussi :p.
@gilou : Oui je suis sur que c'est comme ça ;). Je suis allé chercher le dhcpd.leases directement dans le switch ;). Merci pour le second script le 1er marche très bien mais je le prends quand même on ne sait jamais =).

Reply

Marsh Posté le 30-06-2015 à 10:44:04    

Je voulais te montrer dans ma solution:
1) comment mettre toutes les infos utiles dans un hash
2) Trier les clés du hash en fonction d'un des champs du hash pour le parcourir dans l'ordre voulu et afficher les infos utiles.
 
Bon, je ne sais pas quel constructeur a fait ton switch, mais manifestement, il ne respecte pas les specs prévues pour ce fichier.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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