Sed, remplacer occurences dans 1 fichier

Résolu/Fermé
nicnictout Messages postés 11 Date d'inscription vendredi 25 septembre 2009 Statut Membre Dernière intervention 8 janvier 2014 - 8 sept. 2010 à 11:49
nicnictout Messages postés 11 Date d'inscription vendredi 25 septembre 2009 Statut Membre Dernière intervention 8 janvier 2014 - 8 sept. 2010 à 17:05
Bonjour,

Je travail actuellement sur un petit script mais qui me prend gentiment la tête depuis hier maintenant :)

Voila mon souci, je cherche a ne remplacer qu'une seule fois un pattern précis répété lui, plusieurs fois dans le même fichier.

Ex: voici mon fichier d'imput
<servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

 <servlet>
        <servlet-name>invoker</servlet-name>
        <servlet-class>
          org.apache.catalina.servlets.InvokerServlet
        </servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>


Je voudrais changer juste les valeurs en gras dans mon fichier, sachant que seules les balises sont fixes, ce qu'il y a entre les balises peut varier.

J'ai tenté pas mal de chose:

- suppression des lignes puis insert avec sed, problème, dans ma suppression je dois mettre comme motif délimiteur <load-on-startup>1</load-on-startup>, sinon cela s'arrête trop tot, et du coup après mon insert se fait a chaque </servlet> du fichier...

- j'ai voulu essayé de supprimer les lignes entre mes motifs, tout en les excluant (les motifs) de façon a garder le <load-on-startup>1</load-on-startup> qui est lui unique dans le fichier (c'est la seule ligne du paragraphe unique). Mais impossible, a croire que la syntaxe n'est valide qu'en affichage.

Quelqu'un pourrait il m'aider sur ce problème


PS: question subsidiaire, j'ai vu quelques personnes poser la question, mais pas vu de réponses appropriées, comment fait on avec sed pour n'impacter que la nième occurence dans 1 fichier et pas dans une ligne.

D'avance merci a tous
A voir également:

5 réponses

jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 897
8 sept. 2010 à 14:36
Ok, donc on va tenter une approche différente...

$ cat foo
<servlet>                   
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>                                                              
            <param-name>debug</param-name>                                        
            <param-value>0</param-value>                                          
        </init-param>                                                             
        <init-param>                                                              
            <param-name>motif</param-name>                                        
            <param-value>motif</param-value>                                      
        </init-param>                                                             
        <load-on-startup>1</load-on-startup>                                      
    </servlet>                                                                    

    <servlet>
        <servlet-name>invoker</servlet-name>
        <servlet-class>                     
          org.apache.catalina.servlets.InvokerServlet
        </servlet-class>                             
        <init-param>                                 
            <param-name>debug</param-name>           
            <param-value>0</param-value>             
        </init-param>                                
        <load-on-startup>2</load-on-startup>         
    </servlet>                                       

 <servlet>
        <servlet-name>ssi</servlet-name>
        <servlet-class>                 
          org.apache.catalina.ssi.SSIServlet
        </servlet-class>                    
        <init-param>                        
          <param-name>motif</param-name>    
          <param-value>motif</param-value>  
        </init-param>                       
        <init-param>                        
          <param-name>debug</param-name>    
          <param-value>0</param-value>      
        </init-param>                       
        <init-param>                        
          <param-name>motif</param-name>    
          <param-value>motif</param-value>  
        </init-param>                       
        <init-param>                        
          <param-name>isVirtualWebappRelative</param-name>
          <param-value>0</param-value>                    
        </init-param>                                     
        <load-on-startup>4</load-on-startup>              
    </servlet>  
                                          
$ sed '/<servlet>/{                    
> :z                                                      
> N                                                       
> \|</servlet>$|!bz                                       
> /<load-on-startup>1</{                                  
> s|<param-name.*|<param-name>new_motif</param-name>|2M   
> s|<param-value.*|<param-value>new_motif</param-value>|2M}
> }                                                        
> ' foo 
                                                   
<servlet>                                                  
        <servlet-name>default</servlet-name>               
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>                                                              
            <param-name>debug</param-name>                                        
            <param-value>0</param-value>                                          
        </init-param>                                                             
        <init-param>                                                              
            <param-name>new_motif</param-name>                                    
            <param-value>new_motif</param-value>                                  
        </init-param>                                                             
        <load-on-startup>1</load-on-startup>                                      
    </servlet>                                                                    

    <servlet>
        <servlet-name>invoker</servlet-name>
        <servlet-class>                     
          org.apache.catalina.servlets.InvokerServlet
        </servlet-class>                             
        <init-param>                                 
            <param-name>debug</param-name>           
            <param-value>0</param-value>             
        </init-param>                                
        <load-on-startup>2</load-on-startup>         
    </servlet>

 <servlet>
        <servlet-name>ssi</servlet-name>
        <servlet-class>
          org.apache.catalina.ssi.SSIServlet
        </servlet-class>
        <init-param>
          <param-name>motif</param-name>
          <param-value>motif</param-value>
        </init-param>
        <init-param>
          <param-name>debug</param-name>
          <param-value>0</param-value>
        </init-param>
        <init-param>
          <param-name>motif</param-name>
          <param-value>motif</param-value>
        </init-param>
        <init-param>
          <param-name>isVirtualWebappRelative</param-name>
          <param-value>0</param-value>
        </init-param>
        <load-on-startup>4</load-on-startup>
    </servlet>
$

;-))
1
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 897
Modifié par jipicy le 8/09/2010 à 16:45
Salut,

$ cat plop   
<servlet>                                             
        <servlet-name>default</servlet-name> 
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> 
        <init-param> 
            <param-name>debug</param-name> 
            <param-value>0</param-value> 
        </init-param> 
        <init-param> 
            <param-name>listings</param-name> 
            <param-value>false</param-value> 
        </init-param> 
        <load-on-startup>1</load-on-startup> 
    </servlet> 

 <servlet> 
        <servlet-name>invoker</servlet-name> 
        <servlet-class> 
          org.apache.catalina.servlets.InvokerServlet 
        </servlet-class> 
        <init-param> 
            <param-name>debug</param-name> 
            <param-value>0</param-value> 
        </init-param> 
        <load-on-startup>2</load-on-startup> 
    </servlet>     
                                    
$ sed '/<servlet>/,/<load-on-startup>1/{ 
\|</init-param>|,\|</init-param>|{                          
s|<param-name.*|<param-name>new_motif</param-name>| 
s|<param-value.*|<param-value>new_motif</param-value>| 
}                                                      
}                                                      
' plop   
                                               
<servlet> 
        <servlet-name>default</servlet-name> 
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> 
        <init-param> 
            <param-name>debug</param-name> 
            <param-value>0</param-value> 
        </init-param> 
        <init-param> 
            <param-name>new_motif</param-name> 
            <param-value>new_motif</param-value> 
        </init-param> 
        <load-on-startup>1</load-on-startup> 
    </servlet> 

 <servlet> 
        <servlet-name>invoker</servlet-name> 
        <servlet-class> 
          org.apache.catalina.servlets.InvokerServlet 
        </servlet-class> 
        <init-param> 
            <param-name>debug</param-name> 
            <param-value>0</param-value> 
        </init-param> 
        <load-on-startup>2</load-on-startup> 
    </servlet> 
$

;-))

$ man woman
Il n'y a pas de page de manuel pour woman.

GNU/Linux : Gnu/Linux is Not Ubuntu !
0
nicnictout Messages postés 11 Date d'inscription vendredi 25 septembre 2009 Statut Membre Dernière intervention 8 janvier 2014
8 sept. 2010 à 14:10
Salut,

merci de ta réponse jipicy.

Alors ta solution ne fonctionne que partiellement, mais c'est peut être de ma faute, mon exemple ne correspondait qu'un a un petit morceau de mon fichier.

Du coup ta commande applique les modifs sur l'ensemble du doc, comme si il ne tenait pas compte du délimiteur avec "<load-on-startup>1</load-on-startup>"
Je confirme, c'est bien la seule ligne unique par paragraphe.

Je n'ai pas trouvé sur ce site comment mettre des fichiers en PJ, je t'aurais joint le fichier en entier du coup.

Je vais essayé de voir pourquoi il déborde des 2 motifs délimiteurs.

En attendant, voici un ex plus complet de mon fichier après application de ta commande:

<servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>new_motif</param-name>
            <param-value>new_motif</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>invoker</servlet-name>
        <servlet-class>
          org.apache.catalina.servlets.InvokerServlet
        </servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>

 <servlet>
        <servlet-name>ssi</servlet-name>
        <servlet-class>
          org.apache.catalina.ssi.SSIServlet
        </servlet-class>
        <init-param>
          <param-name>new_motif</param-name>
          <param-value>new_motif</param-value>
        </init-param>
        <init-param>
          <param-name>debug</param-name>
          <param-value>0</param-value>
        </init-param>
        <init-param>
          <param-name>new_motif</param-name>
          <param-value>new_motif</param-value>
        </init-param>
        <init-param>
          <param-name>isVirtualWebappRelative</param-name>
          <param-value>0</param-value>
        </init-param>
        <load-on-startup>4</load-on-startup>
    </servlet>


Comme tu peux le voir, il a modifié bien au delà des délimiteurs...

Mais merci quand même de ta contribution, cela me permet d'avancer un peu :)
0
nicnictout Messages postés 11 Date d'inscription vendredi 25 septembre 2009 Statut Membre Dernière intervention 8 janvier 2014
Modifié par nicnictout le 8/09/2010 à 16:15
Youpiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii

ca marche, j'essayais de mettre toute ta commande sur une seule et même ligne, mais en respectant la syntaxe comme tu l'avais écrite cela fonctionne parfaitement.

Mil merci a toi ;)

PS: si tu as 5min 1 de ces 4 pour m'expliquer un peu la commande, enfin surtout:
:z                                                      
N                                                       
\|</servlet>$|!bz
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 897
8 sept. 2010 à 16:58
Sur une seule ligne ça donne ça :

sed '/<servlet>/{:z;N;\|</servlet>$|!bz;/<load-on-startup>1</{s|<param-name.*|<param-name>new_motif</param-name>|2M;s|<param-value.*|<param-value>new_motif</param-value>|2M};}' foo


Après pour les explications :

/<servlet>/
Si la ligne contient le motif

{
Début regroupement de commandes


:z
On définit une étiquette (pour s'y brancher plus tard)


N
On ajoute la ligne suivante

\|</servlet>$|!bz
Si la ligne ne se finit pas ($ représente la fin de ligne et ! la négation) par le motif "</servlet>", on se branche (b) à l'étiquette (z) et on recommence (on ajoute une nouvelle ligne jusqu'à ce qu'elle se termine par le motif)


/<load-on-startup>1</
Donc une fois le motif "</servlet>" de fin rencontré, si la ligne dans l'espace de travail contient le motif "<load-on-startup>1<" on applique les commandes suivantes

{
Nouveau regroupements de commandes


s|<param-name.*|<param-name>new_motif</param-name>|2M
s|<param-value.*|<param-value>new_motif</param-value>|2M}

Et on opère les substitutions adéquates, qui ne s'appliquent qu'à la seconde occurrence pour chaque ligne.
(Pour les explications concernant le paramètre "M", voir Le modificateur "M" dans la FAQ sur SED)


}
Fin 1er regroupement de commandes

}
Fin 2ème regroupement de commandes
0

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

Posez votre question
nicnictout Messages postés 11 Date d'inscription vendredi 25 septembre 2009 Statut Membre Dernière intervention 8 janvier 2014
8 sept. 2010 à 17:05
oki, donc j'avais zapé les ; en fait. C'est bon a savoir.

Merci pour les explications c'est maintenant beaucoup plus claire ;)

Bonne continuation
0