[PERL]-Compter en hexa

Fermé
blux Messages postés 25999 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 23 avril 2024 - 18 sept. 2007 à 16:48
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 - 21 sept. 2007 à 12:33
Bonjour,

je chercher un moyen de générer une série de nombre hexadécimaux en PERL en connaissant le début et la fin, mais je ne sais pas comment faire (je viens de me pendre avec la doc de pack/unpack ;-)).

J'ai un truc sous cette forme (extrait XML) :
        <Devices start_dev="005E" end_dev="005F"/>
        <Devices start_dev="0067" end_dev="0069"/>
        <Devices start_dev="006F" end_dev="006F"/>
        <Devices start_dev="0097" end_dev="009B"/>
        <Devices start_dev="00AA" end_dev="00AF"/>
        <Devices start_dev="00D2" end_dev="00D4"/>
        <Devices start_dev="00D6" end_dev="00DB"/>
        <Devices start_dev="00DF" end_dev="00DF"/>
        <Devices start_dev="00E4" end_dev="00E7"/>
        <Devices start_dev="00EB" end_dev="00FE"/>
        <Devices start_dev="0100" end_dev="0104"/>
        <Devices start_dev="0106" end_dev="0106"/>
        <Devices start_dev="011D" end_dev="011D"/>
Et je voudrais récupérer une liste comme ça :

005E, 005F, 0067, 0068, 0069, 006F, 0097, 0098, 0099, 009A, 009B, 00AA...

sachant que j'ai parfois des intervalles. Je devrais pourvoir récupérer mes bornes de début et de fin, mais faire générer les valeurs intermédiaires en hexa, je coince.

Si quelqu'un avait une idée (compréhensible par un humain qui n'est pas trappu en PERL :-))

Merci d'avance.
A voir également:

15 réponses

lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
18 sept. 2007 à 23:15
Salut,

voici une possibilité
$ cat blux
<Devices start_dev="005E" end_dev="005F"/>
<Devices start_dev="0067" end_dev="0069"/>
<Devices start_dev="006F" end_dev="006F"/>
<Devices start_dev="0097" end_dev="009B"/>
<Devices start_dev="00AA" end_dev="00AF"/>
<Devices start_dev="00D2" end_dev="00D4"/>
<Devices start_dev="00D6" end_dev="00DB"/>
<Devices start_dev="00DF" end_dev="00DF"/>
<Devices start_dev="00E4" end_dev="00E7"/>
<Devices start_dev="00EB" end_dev="00FE"/>
<Devices start_dev="0100" end_dev="0104"/>
<Devices start_dev="0106" end_dev="0106"/>
<Devices start_dev="011D" end_dev="011D"/>
$ perl -ne'/"([\da-f]{4})".*"([\da-f]{4})"/i;for$e(hex($1)..hex($2)){printf"%.4X,",$e}' blux && echo
005E,005F,0067,0068,0069,006F,0097,0098,0099,009A,009B,00AA,00AB,00AC,00AD,00AE,00AF,00D2,00D3,00D4,00D6,00D7,00D8,00D9,00DA,00DB,00DF,00E4,00E5,00E6,00E7,00EB,00EC,00ED,00EE,00EF,00F0,00F1,00F2,00F3,00F4,00F5,00F6,00F7,00F8,00F9,00FA,00FB,00FC,00FD,00FE,0100,0101,0102,0103,0104,0106,011D,
$
j'ai utilisé echo pour passage à la ligne
0
blux Messages postés 25999 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 23 avril 2024 3 289
18 sept. 2007 à 23:33
Merci, je vais essayer ça au boulot demain :-)

<mode pénible>
j'avais quand même dit : compréhensible par un humain...;-)
Une question encore : si je lis ce fichier (qui ne contient pas que ça) ligne à ligne, je fais comment pour intégrer ces lignes dans mon programme, vu que je dois générer la séquence à chaque nouvelle entité XML que je trouve ?
</mode pénible>
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
18 sept. 2007 à 23:50
si je lis ce fichier (qui ne contient pas que ça) ligne à ligne, je fais comment pour intégrer ces lignes dans mon programme, vu que je dois générer la séquence à chaque nouvelle entité XML que je trouve ?

comme j'ai du mal à comprendre le langage humain ;-)) veux tu me donner un exemple concret
0
blux Messages postés 25999 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 23 avril 2024 3 289
19 sept. 2007 à 09:18
Début de mon fichier :
<SymCLI_ML>
  <symmetrix id="000184502760">
    <Devmask_Database_Record director="FA-3A" port="0">
      <Db_Record originator_port_wwn="10000000c92eb5fb"
           awwn_node_name="10000000c92eb5fb" awwn_port_name="10000000c92eb5fb">
        <Devices start_dev="0000" end_dev="001F"/>
        <Devices start_dev="0070" end_dev="007F"/>
        <Devices start_dev="00B0" end_dev="00BF"/>
        <Devices start_dev="012E" end_dev="0130"/>
        <Devices start_dev="0164" end_dev="0168"/>
        <Devices start_dev="0205" end_dev="0205"/>
      </Db_Record>
      <Db_Record originator_port_wwn="10000000c92eb544"
           awwn_node_name="152101a001dbs" awwn_port_name="D1-08">
        <Devices start_dev="0020" end_dev="0041"/>
        <Devices start_dev="0080" end_dev="0085"/>
        <Devices start_dev="0087" end_dev="0088"/>
        <Devices start_dev="008A" end_dev="008F"/>
        <Devices start_dev="00C2" end_dev="00C3"/>
        <Devices start_dev="0131" end_dev="013C"/>
        <Devices start_dev="013E" end_dev="0146"/>
        <Devices start_dev="014F" end_dev="015D"/>
        <Devices start_dev="0160" end_dev="0163"/>
        <Devices start_dev="0169" end_dev="016B"/>
      </Db_Record>
      <Db_Record originator_port_wwn="10000000c92eb6ee"
           awwn_node_name="10000000c92eb6ee" awwn_port_name="10000000c92eb6ee">
        <Devices/>
      </Db_Record>
      <Db_Record originator_port_wwn="10000000c92eb4d3"
           awwn_node_name="10000000c92eb4d3" awwn_port_name="10000000c92eb4d3">
        <Devices start_dev="0089" end_dev="0089"/>
      </Db_Record>
      <Db_Record originator_port_wwn="10000000c92eb5ef"
           awwn_node_name="10000000c92eb5ef" awwn_port_name="10000000c92eb5ef">
        <Devices start_dev="0042" end_dev="004F"/>
      </Db_Record>
      <Db_Record originator_port_wwn="10000000c92eb5aa"
           awwn_node_name="10000000c92eb5aa" awwn_port_name="10000000c92eb5aa">
        <Devices/>
      </Db_Record>
    </Devmask_Database_Record>
    <Devmask_Database_Record director="FA-3A" port="1">
      <Db_Record originator_port_wwn="10000000c92cfebd"
           awwn_node_name="10000000c92cfebd" awwn_port_name="10000000c92cfebd">
        <Devices/>
      </Db_Record>
      <Db_Record originator_port_wwn="10000000c9341201"
           awwn_node_name="10000000c9341201" awwn_port_name="10000000c9341201">
        <Devices start_dev="0059" end_dev="0059"/>
        <Devices start_dev="0211" end_dev="0211"/>
      </Db_Record>
    </Devmask_Database_Record>
Je dois récupérer les infos concernant Devmask_Database_Record director, Db_Record originator_port_wwn ainsi que la liste des devices (en générant les numéros pour les intervalles). Je vais donc lire mon fichier ligne à ligne pour extraire mes infos mais je ne sais pas comment intégrer la commande ([\da-f]{4})".*"([\da-f]{4})"/i;for$e(hex($1)..hex($2)){printf"%.4X,",$e} pour lui dire qu'elle s'applique à la ligne courante...

C'est plus clair ? :-)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
19 sept. 2007 à 12:36
C'est plus clair ? :-)

c'est ça que tu veux?
#!/usr/bin/perl
use strict;use warnings;
my $devmask = '<Devmask_Database_Record director';
my $dbrecord = '<Db_Record originator_port_wwn';
my $awwn = 'awwn_node_name="';
while (<DATA>){
        s/\n// unless />$/;
        print "\n$_" if /$devmask|$dbrecord|$awwn/;
        if(/"([\da-f]{4})".*"([\da-f]{4})"/i){
                for my $e(hex($1)..hex($2)){printf"%.4X,",$e}
        }
}
print"\n";
__END__
<SymCLI_ML>
<symmetrix id="000184502760">
<Devmask_Database_Record director="FA-3A" port="0">
<Db_Record originator_port_wwn="10000000c92eb5fb"
awwn_node_name="10000000c92eb5fb" awwn_port_name="10000000c92eb5fb">
<Devices start_dev="0000" end_dev="001F"/>
<Devices start_dev="0070" end_dev="007F"/>
<Devices start_dev="00B0" end_dev="00BF"/>
<Devices start_dev="012E" end_dev="0130"/>
<Devices start_dev="0164" end_dev="0168"/>
<Devices start_dev="0205" end_dev="0205"/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb544"
awwn_node_name="152101a001dbs" awwn_port_name="D1-08">
<Devices start_dev="0020" end_dev="0041"/>
<Devices start_dev="0080" end_dev="0085"/>
<Devices start_dev="0087" end_dev="0088"/>
<Devices start_dev="008A" end_dev="008F"/>
<Devices start_dev="00C2" end_dev="00C3"/>
<Devices start_dev="0131" end_dev="013C"/>
<Devices start_dev="013E" end_dev="0146"/>
<Devices start_dev="014F" end_dev="015D"/>
<Devices start_dev="0160" end_dev="0163"/>
<Devices start_dev="0169" end_dev="016B"/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb6ee"
awwn_node_name="10000000c92eb6ee" awwn_port_name="10000000c92eb6ee">
<Devices/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb4d3"
awwn_node_name="10000000c92eb4d3" awwn_port_name="10000000c92eb4d3">
<Devices start_dev="0089" end_dev="0089"/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb5ef"
awwn_node_name="10000000c92eb5ef" awwn_port_name="10000000c92eb5ef">
<Devices start_dev="0042" end_dev="004F"/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb5aa"
awwn_node_name="10000000c92eb5aa" awwn_port_name="10000000c92eb5aa">
<Devices/>
</Db_Record>
</Devmask_Database_Record>
<Devmask_Database_Record director="FA-3A" port="1">
<Db_Record originator_port_wwn="10000000c92cfebd"
awwn_node_name="10000000c92cfebd" awwn_port_name="10000000c92cfebd">
<Devices/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c9341201"
awwn_node_name="10000000c9341201" awwn_port_name="10000000c9341201">
<Devices start_dev="0059" end_dev="0059"/>
<Devices start_dev="0211" end_dev="0211"/>
</Db_Record>
</Devmask_Database_Record>
0
blux Messages postés 25999 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 23 avril 2024 3 289
20 sept. 2007 à 14:08
C'est un peu plus compliqué que ça :

je voudrais avoir une ligne par device qui contienne les informations déjà rencontrées au niveau précédent, pour mon exemple, je souhaiterais obtenir ça en sortie :

000184502760;FA-3A;0;10000000c92eb5fb;0000
000184502760;FA-3A;0;10000000c92eb5fb;0001
...
000184502760;FA-3A;0;10000000c92eb5fb;001F
...
000184502760;FA-3A;0;10000000c92eb544;0020
...
000184502760;FA-3A;1;10000000c9341201;0059
...

Je récupère les infos suivantes : symmetrix id, Devmask_Database_Record director Devmask_Database_Record port, Db_Record originator_port_wwn, Devices start_dev et Devices end_dev, sachant que je n'ai pas toujours de Devices pour un Db_Record originator_port_wwn (cf mon exemple).

J'ai commencé à regarder tes RE, mais j'ai décroché avec if(/"([\da-f]{4})".*"([\da-f]{4})"/i), j'avoue ne pas savoir comment le prendre...
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
20 sept. 2007 à 16:31
#!/usr/bin/perl
use strict;use warnings;
my($id,$dir,$wwn);
while (<DATA>){
  s/\n// unless />$/;
  if(/id="([^"]+)"/)      {$id =$1}
  if(/director="([^"]+)"/){$dir=$1}
  if(/_wwn="([^"]+)"/)    {$wwn=$1}

  if(/"([\da-f]{4})".*"([\da-f]{4})"/i){
    for my $e(hex($1)..hex($2)){
      printf"%s;%s;%s;%.4X\n",$id,$dir,$wwn,$e
    }
  }
}
print"\n";
__END__
<SymCLI_ML>
<symmetrix id="000184502760">
<Devmask_Database_Record director="FA-3A" port="0">
<Db_Record originator_port_wwn="10000000c92eb5fb"
awwn_node_name="10000000c92eb5fb" awwn_port_name="10000000c92eb5fb">
<Devices start_dev="0000" end_dev="001F"/>
<Devices start_dev="0070" end_dev="007F"/>
<Devices start_dev="00B0" end_dev="00BF"/>
<Devices start_dev="012E" end_dev="0130"/>
<Devices start_dev="0164" end_dev="0168"/>
<Devices start_dev="0205" end_dev="0205"/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb544"
awwn_node_name="152101a001dbs" awwn_port_name="D1-08">
<Devices start_dev="0020" end_dev="0041"/>
<Devices start_dev="0080" end_dev="0085"/>
<Devices start_dev="0087" end_dev="0088"/>
<Devices start_dev="008A" end_dev="008F"/>
<Devices start_dev="00C2" end_dev="00C3"/>
<Devices start_dev="0131" end_dev="013C"/>
<Devices start_dev="013E" end_dev="0146"/>
<Devices start_dev="014F" end_dev="015D"/>
<Devices start_dev="0160" end_dev="0163"/>
<Devices start_dev="0169" end_dev="016B"/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb6ee"
awwn_node_name="10000000c92eb6ee" awwn_port_name="10000000c92eb6ee">
<Devices/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb4d3"
awwn_node_name="10000000c92eb4d3" awwn_port_name="10000000c92eb4d3">
<Devices start_dev="0089" end_dev="0089"/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb5ef"
awwn_node_name="10000000c92eb5ef" awwn_port_name="10000000c92eb5ef">
<Devices start_dev="0042" end_dev="004F"/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb5aa"
awwn_node_name="10000000c92eb5aa" awwn_port_name="10000000c92eb5aa">
<Devices/>
</Db_Record>
</Devmask_Database_Record>
<Devmask_Database_Record director="FA-3A" port="1">
<Db_Record originator_port_wwn="10000000c92cfebd"
awwn_node_name="10000000c92cfebd" awwn_port_name="10000000c92cfebd">
<Devices/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c9341201"
awwn_node_name="10000000c9341201" awwn_port_name="10000000c9341201">
<Devices start_dev="0059" end_dev="0059"/>
<Devices start_dev="0211" end_dev="0211"/>
</Db_Record>
</Devmask_Database_Record>
                         
0
blux Messages postés 25999 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 23 avril 2024 3 289
20 sept. 2007 à 16:51
Waouh !!!

super-balaise! il me manque juste 2 choses : le port du meta Devmask_Database_Record et la compréhension de ce qui est écrit :-)

J'ai voulu faire moi-même la modif en regardant comment était faite la ligne qui extrait les dev, mais j'aurais pas dû (quand on sait pas, on touche pas...)
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
20 sept. 2007 à 18:41
pour les explications un peu plus tard ;-))
#!/usr/bin/perl
use strict;use warnings;
my($id,$dir,$p,$wwn);
while (<DATA>){
#s/\n// unless />$/;
  if(/id      ="([^"]+)"/x){$id =$1}
  if(/director="([^"]+)"/x){$dir=$1}
  if(/_wwn    ="([^"]+)"/x){$wwn=$1}
  if(/port    ="([^"]+)"/x){$p  =$1}

  if(/"([\da-f]{4})".*"([\da-f]{4})"/i){
    for my $e(hex($1)..hex($2)){
      printf"%s;%s;%s;%s;%.4X\n",$id,$dir,$p,$wwn,$e
    }
  }
}
print"\n";
__END__
<SymCLI_ML>
<symmetrix id="000184502760">
<Devmask_Database_Record director="FA-3A" port="0">
<Db_Record originator_port_wwn="10000000c92eb5fb"
awwn_node_name="10000000c92eb5fb" awwn_port_name="10000000c92eb5fb">
<Devices start_dev="0000" end_dev="001F"/>
<Devices start_dev="0070" end_dev="007F"/>
<Devices start_dev="00B0" end_dev="00BF"/>
<Devices start_dev="012E" end_dev="0130"/>
<Devices start_dev="0164" end_dev="0168"/>
<Devices start_dev="0205" end_dev="0205"/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb544"
awwn_node_name="152101a001dbs" awwn_port_name="D1-08">
<Devices start_dev="0020" end_dev="0041"/>
<Devices start_dev="0080" end_dev="0085"/>
<Devices start_dev="0087" end_dev="0088"/>
<Devices start_dev="008A" end_dev="008F"/>
<Devices start_dev="00C2" end_dev="00C3"/>
<Devices start_dev="0131" end_dev="013C"/>
<Devices start_dev="013E" end_dev="0146"/>
<Devices start_dev="014F" end_dev="015D"/>
<Devices start_dev="0160" end_dev="0163"/>
<Devices start_dev="0169" end_dev="016B"/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb6ee"
awwn_node_name="10000000c92eb6ee" awwn_port_name="10000000c92eb6ee">
<Devices/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb4d3"
awwn_node_name="10000000c92eb4d3" awwn_port_name="10000000c92eb4d3">
<Devices start_dev="0089" end_dev="0089"/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb5ef"
awwn_node_name="10000000c92eb5ef" awwn_port_name="10000000c92eb5ef">
<Devices start_dev="0042" end_dev="004F"/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c92eb5aa"
awwn_node_name="10000000c92eb5aa" awwn_port_name="10000000c92eb5aa">
<Devices/>
</Db_Record>
</Devmask_Database_Record>
<Devmask_Database_Record director="FA-3A" port="1">
<Db_Record originator_port_wwn="10000000c92cfebd"
awwn_node_name="10000000c92cfebd" awwn_port_name="10000000c92cfebd">
<Devices/>
</Db_Record>
<Db_Record originator_port_wwn="10000000c9341201"
awwn_node_name="10000000c9341201" awwn_port_name="10000000c9341201">
<Devices start_dev="0059" end_dev="0059"/>
<Devices start_dev="0211" end_dev="0211"/>
</Db_Record>
</Devmask_Database_Record>
0
blux Messages postés 25999 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 23 avril 2024 3 289
20 sept. 2007 à 22:14
J'avais fini par mettre une deuxième ligne, auparavant j'ai voulu essayer comme ce qui est fait pour extraire mes dev, mais ça l'a pas fait...
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
21 sept. 2007 à 00:17
dit ce qui ne va pas, sur le bout de fichier que tu m'as donnée ça marche, mais c'est vrai que ce n'est pas évident
0
blux Messages postés 25999 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 23 avril 2024 3 289
21 sept. 2007 à 09:17
Je l'ai refait ce matin, à tête reposée, ça va mieux :
  if (/"(FA-\d{1,2}[AB])".*"([\d])"/i)
  {
    $dir=$1;
    $por=$2;
  }
C'est sans doute pas optimisé, mais je ne suis qu'un humain ;-)
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
21 sept. 2007 à 10:47
Affiche ton script modifié.

A vrai dire tu n'as pas besoin de faire comme ça, mais bon, je n'ai rien contre ;-)
Comme promis je vais t'expliquer ce que j'ai écrit, et tu verras que c'est vraiment humain :-)
0
blux Messages postés 25999 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 23 avril 2024 3 289
21 sept. 2007 à 11:01
while (<LIRE>)
{
  s/\n// unless />$/;
  if (/id      ="([^"]+)"/x)
  {
    $id=$1;
  }
  if (/"(FA-\d{1,2}[AB])".*"([\d])"/i)
  {
    $dir=$1;
    $por=$2;
  }
  if (/_wwn    ="([^"]+)"/x)
  {
    $wwn=$1;
  }
  if (/"([\da-f]{4})".*"([\da-f]{4})"/i)
  {
    for my $e(hex($1)..hex($2))
    {
      printf"%s;%s%s;%s;%.4X\n",$id,$dir,$por,$wwn,$e;
    }
  }
}

J'ai fini par presque tout comprendre excepté le ="([^"]+)

Mais je suis intéressé par une amélioration de mon if (/"(FA-\d{1,2}[AB])".*"([\d])"/i), même si elle n'est pas humaine (c'est juste pour voir ;-))
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
21 sept. 2007 à 12:33
"([^"]+) "

trouve une " suivi d'un caractère non guillemet(une fois minimum) suivi d'une guillemet
ce qui permet de ne pas arriver sur la deuxième paire de guillemets

une amélioration de mon if (/"(FA-\d{1,2}[AB])".*"([\d])"/i),
peut être ça, mais je n'ai pas testé

if (/"(FA-[^"]+)".*"([\d])"/i)

0