Forum Programmation.shell Modifier un fichier avec Awk à partir de données extraites d'un autre fichier

Posté par  .
Étiquettes :
0
31
août
2012

Salut !
Alors voilà, j'ai un petit problème à vous soumettre

J'ai un fichier1 avec des données:

Var1.1 Var1.2 Var1.3
Var2.1 Var2.2 Var2.3
Var3.1 Var3.2 Var3.3

Ainsi qu'un fichier2 que j'aimerais modifier à l'aide de ces données:

File2 (origine)

pattern with Var2.1
some text…

File2(modifié)

pattern with Var2.1
Here I want to add Var2.2 and Var2.3
some text

Ma première solution est d'utiliser AWK, mais pour cela, il me faut pouvoir imbriquer une commande bash dedans et d'en récupérer le resultat. Voila en gros mon algorithme:

  • Trouver le pattern dans le fichier2
  • Lorsque Awk trouve le pattern, il appelle un script externe qui lui renvoie des valeurs du fichier 1
  • Awk édite le fichier en conséquence

N'hésitez pas à me proposer des solutions plus élégantes, plus efficaces auqxquelles je n'aurais pas pensé si jamais vous en avez !

Merci d'avance !

  • # FNR

    Posté par  (site web personnel) . Évalué à 5.

    Salut,

    en awk il y a la variable FNR qui donne le numéro de ligne du fichier en cours de lecture et NR le nombre de ligne total. Ainsi tu peux séparer la lecture du premier et du second fichier.

    awk 'NR == FNR { mise en cache du file1 dans un tableau; next } {traitement du fichier 2} }' file1 file2
    
    
    • [^] # Re: FNR

      Posté par  . Évalué à 0.

      Ok ! Merci ! =)
      Autre question sur le awk, tant qu'on y est:

      Est ce que je peux mettre une expression régulière représentant plusieurs lignes dans les conditions à valider ?

      Je m'explique:

      public nimporteQuelleFonction1(){

      }

      public maFonction(){

      }

      public maFonction2(){

      }

      public nimporteQuelleFonction2(){

      }

      Je veux insérer quelque chose à la fin des fonction "maFonctionXX". L'idée aurait été de chercher à matcher avec
      /}\n\npublic maFonction/{printf("code à ajouter %s",$0)}

      • [^] # Re: FNR

        Posté par  . Évalué à 1.

        en fait je crois que j'ai trouvé:

        /^}$/{getline;getline; if($0~/public maFonction/){printf("code à ajouter %s",$0)}}
        
        
        • [^] # Re: FNR

          Posté par  (site web personnel) . Évalué à 2.

          Je n'ai pas vraiment compris ce que tu voulais tu peux me mettre un exemple d'output ?

          • [^] # Re: FNR

            Posté par  . Évalué à 1.

            en fait, j'ai mal choisi mon exemple, en revoila un nouveau:

            public maFonction(){
            …
            }
            
            public nimporteQuelleFonction1(){
            …
            }
            
            public maFonction2(){
            …
            }
            
            public nimporteQuelleFonction2(){
            …
            }
            
            

            Objectif: ajouter du code à la fin de chaque maFonctionXXX pour obtenir quelquechose comme ca:

            public maFonction(){
            …
            nouveau code
            }
            
            public nimporteQuelleFonction1(){
            …
            }
            
            public maFonction2(){
            …
            nouveau code
            }
            
            public nimporteQuelleFonction2(){
            …
            }
            
            
            • [^] # Re: FNR

              Posté par  (site web personnel) . Évalué à 2.

              si ton code est bien indenté tu n'as qu'à matcher sur les lignes où il y à } au début de ligne :

              awk '{ if ($0 ~ /^}$/) { print "nouveau code" ; print } else { print }}' file
              
              
              • [^] # Re: FNR

                Posté par  . Évalué à 0.

                non parce que dans ce cas là, il va m'ajouter du code à la fin de toutes les fonctions, meme dans les nimporteQuelleFonctionXX où je n'en veux pas.

                • [^] # Re: FNR

                  Posté par  (site web personnel) . Évalué à 4.

                  Alors rajoute un flag

                  awk '/public maFonction/ {flag=1} { if ($0 ~ /^}$/ && flag == 1) { print "nouveau code" ; print ; flag=0 } else { print }}' file
                  
                  
                  • [^] # Re: FNR

                    Posté par  . Évalué à 1.

                    c'est tout bête… !

                    Merci pour ta patience ;)

                  • [^] # Re: FNR

                    Posté par  . Évalué à 3.

                    sauf que si je ne me trompe pas ca va matcher avec toutes les } qui se trouve apres maFonction

                    donc il ne faut pas qu'il y ait d'autres codes avec des {} dedans

                    • [^] # Re: FNR

                      Posté par  (site web personnel) . Évalué à 2.

                      Pas réellement ça va matcher avec le premier } qui est au tout début de ligne, cela veut dire que si l'indentation est bonne cela fonctionne bien.

                      Si on veut vraiment s'amuser à aller à la fin de la fonction sans s'amuser avec l'indentation ça correspond à un truc plus compliqué :

                      awk '
                      
                      /public maFonction/ {flag=1;x=0} 
                      
                      flag {
                      x-=gsub("}","}");
                      x+=gsub("{","{"); 
                      if (x == 0) {print "nouveau code";print;flag=0;next}} 
                      
                      1' file
                      
                      

                      y'a peut être un moyen plus élégant pour compter les { } mais je ne connais pas. Bon ça ne fonctionne pas si le premier { n'est pas sur la même ligne que la déclaration de la fonction.

        • [^] # Re: FNR

          Posté par  . Évalué à 1.

          echec… => $0 représente maintenant la ligne public maFonctionXXX, du coup, si j'ajoute du code, ca va me donner:

          } 
          
          mon code
          }
          
          public ma FonctionXXX
          
          

          au lieu de

          mon code
          }
          
          public ma FonctionXXX
          
          

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.