OVH Cloud OVH Cloud

sed : commande à simplifier

12 réponses
Avatar
SDC
Bonjour,

Je cherche =E0 simplifier le pipe suivant en une seule commande "sed" :

sed "/toto/,\$!d" | sed "1s|toto|titi|"

L'objectif est de chercher la premi=E8re ligne qui satisfait
l'expression r=E9guli=E8re "toto", de jeter les lignes avant, de
remplacer "toto" par "titi" sur cette premi=E8re ligne, et de laisser
intact les lignes suivantes (qu'elles satisfassent "toto" ou pas).

Merci d'avance.

---
SDC

10 réponses

1 2
Avatar
Jacques L'helgoualc'h
Le 28-06-2005, SDC a écrit :
Bonjour,


bonjour,

Je cherche à simplifier le pipe suivant en une seule commande "sed" :

sed "/toto/,$!d" | sed "1s|toto|titi|"

L'objectif est de chercher la première ligne qui satisfait
l'expression régulière "toto", de jeter les lignes avant, de
remplacer "toto" par "titi" sur cette première ligne, et de laisser
intact les lignes suivantes (qu'elles satisfassent "toto" ou pas).


sed -n '/toto/!d
:A
$!{
N
b A
}
s//titi/1
p'


Merci d'avance.


de rien, il n'y a plus qu'un seul sed, mais ...
--
Jacques L'helgoualc'h

Avatar
Antoine Leca
En <news:,
SDC va escriure:
Je cherche à simplifier le pipe suivant en une seule commande "sed" :

sed "/toto/,$!d" | sed "1s|toto|titi|"


Pas sûr que ce soit plus simple ni même plus efficace (pas testé)

sed -e "/toto/!d; s|toto|titi|; :boucle" -e "n; b boucle"


Explications (au cas où):

/toto/!d jette tant que l'on a pas vu /toto/
s|toto|titi| fait la substitution (donc sur la 1re qui va bien)
:boucle après, on boucle...
n sur toutes les lignes sans exception, donc on ne
b boucle ... repasse plus par le début du script


Antoine

Avatar
Laurent Wacrenier
SDC écrit:
Je cherche à simplifier le pipe suivant en une seule commande "sed" :

sed "/toto/,$!d" | sed "1s|toto|titi|"


sed -n '1,/toto/s/toto/titi/;/titi/,$p'

Avatar
SDC
Merci.

Mais en fait, j'ai un peu trop allégé mon problème dans mon
explication...
Je veux simplifier :

sed "/^.*toto=([0-9]*).*$/,$!d" | sed "1s|toto=([0-9]*)|1|"

Du coup, je n'ai pas accès à "titi" en dehors de la substitution.
Avatar
Antoine Leca
En news:,
SDC va escriure:
Je veux simplifier :

sed "/^.*toto=([0-9]*).*$/,$!d" | sed "1s|toto=([0-9]*)|1|"

Du coup, je n'ai pas accès à "titi" en dehors de la substitution.


Deuxième essai (inspiré par Laurent):

sed "1,/toto=/{ /toto=/!d; s|toto=([0-9]*)|1|; }"

J'ai enlevé des recherches tout ce qui était superflu (pouvait concorder
avec la chaîne vide).


Antoine

Avatar
SDC
Cela fonctionne mais c'est 36 % plus coûteux que ma version initiale
sur mon exemple. J'aurai pensé qu'un seul "sed" serait profitable,
mais ce n'est plus si évident que cela.

SDC
Avatar
Jacques L'helgoualc'h
Le 28-06-2005, Laurent Wacrenier a écrit :
SDC écrit:
Je cherche à simplifier le pipe suivant en une seule commande "sed" :

sed "/toto/,$!d" | sed "1s|toto|titi|"


sed -n '1,/toto/s/toto/titi/;/titi/,$p'


Heu, non, il peut déjà exister un titi avant toto.

sed '1,/toto/{/toto/!d;s/toto/titi/}'

mais ça ne marchera pas si /toto/ est en première ligne ; gnu sed permet
de commencer à la « zéroième » ligne,

sed '0,/toto/{/toto/!d;s/toto/titi/}'

semble le plus logique, les modifications étant restreintes au début.
--
Jacques L'helgoualc'h


Avatar
Jacques L'helgoualc'h
Le 28-06-2005, Antoine Leca a écrit :
[...]
sed "1,/toto=/{ /toto=/!d; s|toto=([0-9]*)|1|; }"

J'ai enlevé des recherches tout ce qui était superflu (pouvait concorder
avec la chaîne vide).


La récupération de sous-chaîne n'est pas nécessaire non plus : s/toto=//
lui est équivalente (et peut même s'abréger en s/// pour les fainéants).

Le 1,/toto/ ne marche pas avec toto en première ligne, cf. ma réponse à
Laurent.
--
Jacques L'helgoualc'h

Avatar
SDC
Pour un même calcul sur une même machine (Sun Blade 1000 avec Solaris
8) utilisant le pipe précédant, j'obtiens des temps de calcul très
différents selon la commande "sed" que j'utilise :

/usr/ucb/sed : 1.03 secondes (100 %)
/usr/bin/sed : 1.62 secondes (157 %)
/usr/xpg4/bin/sed : 3.63 secondes (352 %)
GNU sed : 4.82 secondes (468 %)

Je veux bien qu'il y ait des différences, mais là ça prend des
proportions énormes, non ?

---
SDC
Avatar
Laurent Wacrenier
Antoine Leca écrit:
sed "1,/toto=/{ /toto=/!d; s|toto=([0-9]*)|1|; }"


Il y a un test en trop :

sed "1,/toto=/{ s|toto=([0-9]*)|1|p; d;}"

1 2