Sed, remplacer occurences dans 1 fichier
Résolu
nicnictout
Messages postés
11
Date d'inscription
Statut
Membre
Dernière intervention
-
nicnictout Messages postés 11 Date d'inscription Statut Membre Dernière intervention -
nicnictout Messages postés 11 Date d'inscription Statut Membre Dernière intervention -
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
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
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:
- Sed, remplacer occurences dans 1 fichier
- Fichier bin - Guide
- Fichier epub - Guide
- Fichier rar - Guide
- Comment réduire la taille d'un fichier - Guide
- Fichier .dat - Guide
5 réponses
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> $
;-))
Salut,
;-))
$ man woman
Il n'y a pas de page de manuel pour woman.
GNU/Linux : Gnu/Linux is Not Ubuntu !
$ 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 !
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:
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 :)
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 :)
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:
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
Sur une seule ligne ça donne ça :
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
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
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question