remplacement récursif sur des blocs de codes ciblés

remplacement récursif sur des blocs de codes ciblés - Perl - Programmation

Marsh Posté le 24-11-2011 à 08:58:13    

Bonjour.  
 
J'ai un répertoire avec 800 fichiers.  
Dont certains sont nommés A01B1.ext à A08B8.ext, sachant qu'on a tous ces fichiers de A01 à A10.
Tous ces fichiers ont le même squelette de blocs, les mêmes noms de blocs (il y a 50 blocs).
 
nom_1
{
code1
vaviable_i ="1";
}
....
nom_n
{
code_n
vaviable_i ="1";
}
 
Je dois changer pour la liste {nom_3, nom_9, ...nom_i..., nom_40} la valeur de la variable à 0;
 
J'ai vu des solutions pour une partie du problème dans http://forum.hardware.fr/message.p [...] catgroup=0
 
Mais, je ne sais pas appliqiuer la modification uniquement à la liste {nom_3, nom_9, ...nom_i..., nom_40} qui peut être variable.
Auriez vous des solutions.  
D'avance merci.


Message édité par yozyoz21 le 24-11-2011 à 09:20:01
Reply

Marsh Posté le 24-11-2011 à 08:58:13   

Reply

Marsh Posté le 24-11-2011 à 09:51:16    

Pour l'instant, grâce au topic  
http://forum.hardware.fr/hfr/Progr [...] 7576_1.htm
j'ai trouvé la solution ci dessous. Dites moi ce que vous en pensez.
 
my $file ="";
my @data = ("nom_1" ; "nom_2" ; "nom_3" ; "nom_4" ; "nom_5" ; "nom_6" )
 
 
 
 for( $i=1; $i<8; $i++ )
 {
  for( $i=1; $i<9; $i++ )
  {
   $msg = "0$i";
   $file = "A0".$i."B".$j.".ext"
   print "$file";
   open IN, $file or die $!;
   while ($intext = <IN> ) {
   foreach $valeur (@data){
    if $intext = ~ /$valeur/){
     $v=~ s/VARIABLE = "1";/VARIABLE = "0";  
    }
    }
   }
  }
 }

Reply

Marsh Posté le 24-11-2011 à 09:57:11    

Ensuite, je souhaite exécuter ces mêmes modifs sur les fichiers  
A01aB1.ext à A08aB8.ext et A01bB1.ext à A01B8.ext
 
J'ai changé un peu le code :  
 for( $i=1; $i<8; $i++ )
 {
  for( $i=1; $i<9; $i++ )
  {
   $file = "A0".$i."B".$j.".ext"
   print "$file";
   open IN, $file or die $!;
   while ($intext = <IN> ) {
   foreach $valeur (@data){
    if $intext = ~ /$valeur/){
     $v=~ s/VARIABLE = "1";/VARIABLE = "0";  
    }
    }
   }
  }
 }

Reply

Marsh Posté le 24-11-2011 à 11:11:29    

Le code modifié est :  
    #!/usr/bin/perl
     
    use strict;
    use warnings;
     
    my $file ="";
    my $j = 0 ;
    my $intext = "";
    my $intext2 = "";
    my $valeur = "";
    my $v = "";
    my @data = ("nom_3" , "nom_13" , "nom_20" , "nom_19" , "nom_25" , "nom_35" );
    for ($i=2; $i<9; $i++)
        for ($j=2; $j<9; $j++)
        {
            $file = "A0".$i."B0"$j.".ext";
            print "$file \n";
            open IN, $file or die $!;
            while ($intext = <IN> ) {
            foreach $valeur (@data)
            {
                if ($intext =~ /$valeur/)
                    {
                    print  "valeur ".$valeur." trouvee\n";
                    if ($intext =~ /"VARIABLE"/){
                    print  "valeur ".$intext2." trouvee\n";
                    $intext2=~ s/1/0/;
                    }
                }
             }
             }
        }
 
 
Quand je l'éxecute, il ouvre les fichiers mais ne modifie pas les valeurs.  
 
HELP


Message édité par yozyoz21 le 24-11-2011 à 11:12:06
Reply

Marsh Posté le 24-11-2011 à 12:04:30    

Citation :

Quand je l'éxecute, il ouvre les fichiers mais ne modifie pas les valeurs.  

C'est normal ça, il fait cela pour la valeur qu'il lit (il a copié la ligne lue dans la variable $_ et c'est la dessus qu'il opère), pas pour celle du fichier.
Bon, je vais regarder cela.
Il y a un truc pas clair:
le variable a changer dans un bloc approprié, elle s'appelle comment? VARIABLE?
A+,


Message édité par gilou le 24-11-2011 à 12:17:03

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

Marsh Posté le 24-11-2011 à 12:40:30    

Bon, j'ai rien testé, donc le code est SGDG, mais ça pourrait ressembler à ceci:
 

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. use Tie::File;
  6. my @farray;
  7. my $substitute = 0;
  8. my $regexp = "(3|13|19|20|25|35)";
  9.  
  10. foreach my $i (2..9) {
  11.  foreach my $j (2..9) {
  12.    my $file = "A0${i}B0${j}.ext";
  13.    if (-f $file) {
  14.      tie @farray, 'Tie::File', $file or die "Cannot Tie file $file $!";
  15.      foreach (@farray) {
  16.     if (/nom_\d+/) {
  17.       if (/nom_$regexp/){
  18.         $substitute = 1;
  19.       }
  20.       else {
  21.         $substitute = 0;
  22.       }
  23.     }
  24.     if ($substitute) {
  25.       if (/VARIABLE/) {
  26.         s/1/0/;
  27.       }
  28.     }
  29.      }
  30.      untie @farray;
  31.    }
  32.  }
  33. }


 
foreach my $i (2..9) ==> fait varier automatiquement i de 2 a 9 dans la boucle
my $file = "A0${i}B0${j}.ext"; ==> construit le nom de fichier d'un coup (${i] c'est $i, mais sans les accolades, ce serait pris pour $iB0
if (-f $file) ==> on teste l'existence du fichier
tie @farray, 'Tie::File', $file ==> lie le fichier a un array, les modifications de l'array sont répercutées sur le fichier
untie @farray;  ==> opération inverse, a effectuer lorsque les manipulations du fichier sont achevées
foreach (@farray)  ==> On traite l'array, donc le fichier, ligne à ligne

if (/nom_\d+/) {
   if (/nom_$regexp/){
     $substitute = 1;
   }
   else {
     $substitute = 0;
   }
 }

Reply

Marsh Posté le 24-11-2011 à 12:53:13    

Ici j'ai de la chance, la variable i est en fait une des nombreuses variables du bloc.  
Elle s'appelle DEFAULTVALUE.  
J'ai d'ailleurs dans le code tous les blocs de la forme :  
 
 
   nom_bloc_1   = {
      Description = ...
      ...
      MinValue =....
      MaxValue = ...
      DEFAULTVALUE = "1" ;  
      Variable = " " ;  
      Range = " " ;  
      ...
      }

Reply

Marsh Posté le 24-11-2011 à 12:56:24    

D'ailleurs les noms des blocs sont  
 {cmd1, cmd2, reset1, backup, registery, ...,processing,}

Reply

Marsh Posté le 24-11-2011 à 14:21:07    

yozyoz21 a écrit :

D'ailleurs les noms des blocs sont  
 {cmd1, cmd2, reset1, backup, registery, ...,processing,}

Il faut tous les noms de blocs, pas seulement ceux que tu veux traiter (histoire de pas traiter ceux pas concernés par la substitution alors).
Tu peux alors modifier le code comme suit:  (les valeurs des deux regexp $substblocs et $allblocs sont a modifier en fonction de tes besoins réels)
 

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. use Tie::File;
  6. my @farray;
  7. my $substitute = 0;
  8. my $substblocs = "cmd1|cmd2|reset1";
  9. my $allblocs   = "$substblocs|backup|registery|processing";
  10.  
  11. foreach my $i (2..9) {
  12.  foreach my $j (2..9) {
  13.    my $file = "A0${i}B0${j}.ext";
  14.    if (-f $file) {
  15.      tie @farray, 'Tie::File', $file or die "Cannot Tie file $file $!";
  16.      foreach (@farray) {
  17.     if (/$allblocs/) {
  18.       if (/$substblocs/){
  19.         $substitute = 1;
  20.       }
  21.       else {
  22.         $substitute = 0;
  23.       }
  24.     }
  25.     if ($substitute) {
  26.       if (/DEFAULTVALUE/) {
  27.         s/1/0/;
  28.       }
  29.     }
  30.      }
  31.      untie @farray;
  32.    }
  33.  }
  34. }


 
A+,
 
 
 


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

Marsh Posté le 24-11-2011 à 14:43:55    

Notes que si tous tes blocs sont comme:

Citation :

nom_bloc_1   = {  
      Description = ...  
      ...  
      MinValue =....  
      MaxValue = ...  
      DEFAULTVALUE = "1" ;  
      Variable = " " ;  
      Range = " " ;  
      ...  
      }


et que tu n'as pas de { ou } ailleurs dans ton fichier, c'est encore plus facile:
 

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. use Tie::File;
  6. my @farray;
  7. my $substitute = 0;
  8. my $subcmds = "cmd1|cmd2|reset1";
  9.  
  10. foreach my $i (2..9) {
  11.  foreach my $j (2..9) {
  12.    my $file = "A0${i}B0${j}.ext";
  13.    if (-f $file) {
  14.      tie @farray, 'Tie::File', $file or die "Cannot Tie file $file $!";
  15.      foreach (@farray) {
  16.         if (/\{/ and /$subcmds/)  {$substitute = 1; next}
  17.         if (/\}/)                 {$substitute = 0; next}
  18.         if ($substitute and /DEFAULTVALUE/) {s/1/0/o};
  19.      }
  20.      untie @farray;
  21.    }
  22.  }
  23. }


A+,


Message édité par gilou le 24-11-2011 à 14:44:39

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

Marsh Posté le 24-11-2011 à 14:43:55   

Reply

Marsh Posté le 24-11-2011 à 15:09:18    

Salut.  
 
Merci beaucoup pour ton avancée.  
Je me suis permis une variante ligne 17 : if (/\}/and !/data/)  {$substitute = 0; next}
 
Comme ca, si on est différent de la ligne recherchée, ca n'applique pas les modifs.  
 
Tu vas me permettre de modifier 180 fichiers automatiquement sur 3 pc, pour 5 blocs parmi 13 pour chaque fichier.

Reply

Marsh Posté le 24-11-2011 à 15:20:26    

>> Comme ca, si on est différent de la ligne recherchée, ca n'applique pas les modifs.  
 
C'est  
if (/\}/and $substitute)  {$substitute = 0; next}  
que tu veux faire en fait
(tu as pas fait attention que c'est sur l'accolade fermante et non plus sur l'ouvrante qu'on est maintenant)
ie changer la valeur de substitute que si c'est necessaire.
J'y avais pensé, mais je ne sais pas, entre un test simple + une assignation inutile ou bien deux teste supplémentaires (le valeur de substitute, et le and sur les deux expressions) ce qui est le plus couteux, alors j'ai opté pour le plus simple à lire.
A+,


Message édité par gilou le 24-11-2011 à 15:22:47

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

Marsh Posté le 24-11-2011 à 22:59:45    

D'ailleurs, ca a marché avec un fichier qui avait des {} dans le header.  
 
J'espère que ce code pourra resservir si des personnes ont des variables à changer dans des xml.  
 
Je souhaite ensuite généraliser :  
Cette fois ci on a pour d'autres fichiers (IHM) le même masque pour les noms de fichiers :  
A01B01 .... AiBj... AnBm     (les i j n m sont dans le nom du fichier).  
Par exemple A = nuit_courant
 
Dans le fichier A01B01 fichiers on retrouve les bouts de codes :  
...
   nuit_courant_partie01_veille = "value01_"+xx+"shortcut01"+extent
   nuit_courant_partie01_reinit = "value02"+xx+"reset01
   nuit_courant_partie01_shunt = "value03"+xx+"shortcut01+B
...
 
Dans le fichier A02B05 fichiers on retrouve les bouts de codes :  
...
   nuit_courant_partie02_veille = "value01_"+xx+"shortcut02"+extent   (les valeurs 01 sont données par la partie A01 du nom du fichier).
   nuit_courant_partie02_reinit = "value02"+xx+"reset05
   nuit_courant_partie02_shunt = "value03"+xx+"shortcut02+B
...
 
 
J'ai 3 fichiers de nuits A01B01 A02B01 A03B01. (pour les autres fichiers je peux me débrouiller).
Je dois les remplacer par 8 fichiers de jours avec :  
remplacement du nom du fichier A = nuit_courant par C= jour_micro_courant
Il faut donc que je créée les 5 autres fichiers pour avoir C01B01.... C08B01....
 
Ce qui donnereait par exemple pour C07B04:  
...
   jour_micro_courant_partie07_veille = "value01_"+xx+"shortcut07"+extent  
   jour_micro_courant_partie07_reinit = "value02"+xx+"reset04
   jour_micro_courant_partie07_shunt = "value03"+xx+"shortcut07+B
...
 
Ensuite, il faudra que j'applique aux fichiers A01 et C01 des modifs à un bloc.  
aux fichiers A02 et C02 des modifs à un autre bloc. MAis avec les réponses ci dessus je devrais m'en sortir.


Message édité par yozyoz21 le 24-11-2011 à 23:07:39
Reply

Sujets relatifs:

Leave a Replay

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

© 2018 Forum. All Rights Reserved.