Perl - Fichier Texte Sed

Perl - Fichier Texte Sed - Perl - Programmation

Marsh Posté le 23-03-2010 à 23:52:46    

Bonjour,
 
Je voudrais savoir si il est possible avec Perl de faire ce que l'on peut faire avec un sed ou un awk sur plusieurs lignes. (capturer entre un motif de début ou un motif de fin)
 
J'ai un fichier texte comme suit:

Code :
  1. [BAL_A]
  2. AAA_BBBB:= Modele
  3. AAA_CCCC:= Fichier1,Fichier2,
  4.             Fichier3,Fichier4,
  5.             Fichier5,Fichier2
  6. AAA_DDDD:= Chaine1,Chaine2,
  7.             Chaine3,Chaine4,
  8.             Chaine4,Chaine5
  9. AAA_EEEE:= Input1,Input2,
  10.             Input3,Input4,
  11.             Input5,Input6
  12. [END_BAL_A]


 
Je voudrais arriver à le remettre en forme comme suit:

Code :
  1. [BAL_A]
  2. AAA_BBBB:= Modele
  3. AAA_CCCC:= Fichier1,Fichier2,Fichier3,Fichier4,Fichier5,Fichier2
  4. AAA_DDDD:= Chaine1,Chaine2,Chaine3,Chaine4,Chaine4,Chaine5
  5. AAA_EEEE:= Input1,Input2,Input3,Input4,Input5,Input6
  6. [END_BAL_A]


 
J'ai donc essayer de capturer le texte avec une expression régulière.
Je prends le texte compris entre AAA_\w{4} et le prochain AAA_ ou [, mais j'ai quelques petits problèmes.
Les lignes 4, 5, 7, 8, 10 et 11 sont supprimées ...  :sarcastic:  
 
Avec le perl, peux-t-on faire une lecture sur plusieurs lignes ?

Reply

Marsh Posté le 23-03-2010 à 23:52:46   

Reply

Marsh Posté le 24-03-2010 à 02:18:34    

:hello:  
Fais voir ton code, qu'on comprenne ce qui y provoque la suppression des lignes.
A+,


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

Marsh Posté le 24-03-2010 à 08:56:56    

gilou a écrit :

:hello:  
Fais voir ton code, qu'on comprenne ce qui y provoque la suppression des lignes.
A+,


 
Bonjour,
 
Voila mon code:
 

Code :
  1. #!/usr/local/bin/perl
  2. open (FICH,"cfg.txt" ) or die("Erreur fichier\n" );
  3. while(<FICH> )
  4. {
  5.     print if /(AAA_\w{4}\:=)/ ... /AAA_\w{4}|\[/;
  6. }
  7. close(FICH);


 
Merci

Reply

Marsh Posté le 24-03-2010 à 14:13:27    

Le comportement que tu as est normal:
/(AAA_\w{4}\:=)/ ... /AAA_\w{4}|\[/ marche comme un switch on/off
Quand tu trouves /(AAA_\w{4}\:=)/ ça met a ON (ligne trouvée incluse), et quand tu trouves ensuite /AAA_\w{4}|\[/ ca met a OFF (après la ligne trouvée), donc:
 
[BAL_A] => Condition à 0 on n'imprime pas
 AAA_BBBB:= Modele => /(AAA_\w{4}\:=)/  met a 1 la condition, et on imprime
 AAA_CCCC:= Fichier1,Fichier2, => Condition a 1: on imprime et /AAA_\w{4}|\[/ remet ensuite a 0 la condition
            Fichier3,Fichier4, => Condition à 0 on n'imprime pas
            Fichier5,Fichier2 => Condition à 0 on n'imprime pas
 AAA_DDDD:= Chaine1,Chaine2, => /(AAA_\w{4}\:=)/  met a 1 la condition, et on imprime
            Chaine3,Chaine4, => Condition a 1: on imprime
            Chaine4,Chaine5 => Condition a 1: on imprime
 AAA_EEEE:= Input1,Input2, => Condition a 1: on imprime et /AAA_\w{4}|\[/ remet ensuite a 0 la condition
            Input3,Input4, => Condition à 0 on n'imprime pas
            Input5,Input6 => Condition à 0 on n'imprime pas
[END_BAL_A] => Condition à 0 on n'imprime pas
 
A+,


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

Marsh Posté le 24-03-2010 à 14:52:30    

Ok, je comprends bien le problème.
Je ne vois pas comment faire pour arriver au résultat souhaité ?
Il faut utiliser une instruction du genre =~s ou une expression réguliére ?

Reply

Marsh Posté le 24-03-2010 à 15:19:03    

Tu peux par exemple faire comme suit:

Code :
  1. #!/usr/local/bin/perl
  2.  
  3. open (FICH,"cfg.txt" ) or die("Erreur fichier\n" );
  4. $print = 0;
  5. while(<FICH> )
  6. {
  7.    if (not $print and /(AAA_\w{4}\:=)/) {
  8.        $print = 1;
  9.    }
  10.    # # Comme les blocs sont contigus,
  11.    # # On peut se passer de cette condition
  12.    # if ($print and /(^,)\s*$/){
  13.    #     $print = 0;
  14.    # }
  15.    if ($print and /\[END_BAL_A\]/){
  16.        $print = 0;
  17.    }
  18.    if ($print) {
  19.        chop if (/,\s*$/);
  20.        s/\s*(.*)/$1/;
  21.        print;
  22.    }
  23. }
  24.  
  25. close(FICH);


L'idée, c'est de positionner un flag qui vaut 1 pour chaque bloc a traiter et 0 ailleurs (ici, les blocs sont contigus donc on ne remet pas a 0 entre deux blocs, sinon, on pourrait le détecter dans ton cas par l'absence de virgule en fin de ligne).
Ensuite j'ai utilisé le fait que les lignes terminées par une virgule perdent leur \n final, mais c'est à adapter selon tes données.
A+,


Message édité par gilou le 24-03-2010 à 15:30:34

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

Sujets relatifs:

Leave a Replay

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