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

  FORUM HardWare.fr
  Programmation
  Perl

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

 

 

 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

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

n°2113037
yozyoz21
Posté le 24-11-2011 à 08:58:13  profilanswer
 

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
mood
Publicité
Posté le 24-11-2011 à 08:58:13  profilanswer
 

n°2113041
yozyoz21
Posté le 24-11-2011 à 09:51:16  profilanswer
 

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";  
    }
    }
   }
  }
 }

n°2113043
yozyoz21
Posté le 24-11-2011 à 09:57:11  profilanswer
 

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";  
    }
    }
   }
  }
 }

n°2113064
yozyoz21
Posté le 24-11-2011 à 11:11:29  profilanswer
 

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
n°2113069
gilou
Modérateur
Modzilla
Posté le 24-11-2011 à 12:04:30  profilanswer
 

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é!  --
n°2113075
gilou
Modérateur
Modzilla
Posté le 24-11-2011 à 12:40:30  profilanswer
 

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;
   }
 }

On trouve un début de bloc. S'il est avec le bon nombre associé, on met le flag $substitute à 1 sinon on le met à 0

if ($substitute) {
   if (/VARIABLE/) {
     s/1/0/;
   }
 }

Si le flag substitute est à 1, et si on a une ligne avec VARIABLE, on fait la substitution
(a mon avis, si c'est variable_i = "1", c'est plutôt s/\"1\"/"0"/; qu'il faut faire, car sinon, votre substitution risque de s'opérer sur les chiffres de i de variable_i)
Bon, c'est à adapter selon la structure de vos blocs et fichiers, mais vous voyez le principe.
 
A+,


Message édité par gilou le 24-11-2011 à 12:47:39

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2113076
yozyoz21
Posté le 24-11-2011 à 12:53:13  profilanswer
 

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 = " " ;  
      ...
      }

n°2113078
yozyoz21
Posté le 24-11-2011 à 12:56:24  profilanswer
 

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

n°2113091
gilou
Modérateur
Modzilla
Posté le 24-11-2011 à 14:21:07  profilanswer
 

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é!  --
n°2113098
gilou
Modérateur
Modzilla
Posté le 24-11-2011 à 14:43:55  profilanswer
 

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é!  --
mood
Publicité
Posté le 24-11-2011 à 14:43:55  profilanswer
 

n°2113102
yozyoz21
Posté le 24-11-2011 à 15:09:18  profilanswer
 

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.

n°2113106
gilou
Modérateur
Modzilla
Posté le 24-11-2011 à 15:20:26  profilanswer
 

>> 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é!  --
n°2113184
yozyoz21
Posté le 24-11-2011 à 22:59:45  profilanswer
 

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

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

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

 

Sujets relatifs
Remplacement de caractère ds un txt[RESOLU] Remplacement d'un swf par une image pour les tablettes
comment faire pour retrouver mes codes indesign ?CSS les blocs
[BASH] parcours récursif et command externe => command not foundCommande awk pour extraire des blocs d'un fichier + regexp sur lignes
Decouper un code recursifexcel remplacement nom dans macro
Menu Dynamique recursif php/mysqlsommer des blocs dan un bloc
Plus de sujets relatifs à : remplacement récursif sur des blocs de codes ciblés


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR