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

2 réponses

1 2
Avatar
Antoine Leca
En <news:slrndc29nd.kfp.lhh+,
Jacques L'helgoualc'h va escriure:
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


Oui.

(et peut même s'abréger en s/// pour les fainéants).


Oui, mais là tu prends des risques avec ton implémentation, et ce n'est plus
conforme POSIX stricto sensu.


Le 1,/toto/ ne marche pas avec toto en première ligne, cf. ma
réponse à Laurent.


Ah oui, celui-là je n'avais pas vu.
Et en dehors de la solution 0 de GNU (ce qui ne va pas être une amélioration
au niveau des performances), les autres manières de contourner ne me
plaisent pas du tout. :-(

Bon, si on prend en plus l'astuce de Laurent pour éviter le test pour d, on
obtient

gsed "0,/toto=/{ s|toto=||p; d; }"

ou

sed "1,/toto=/{ s|toto=||p; d; }"

si toto= ne peut pas être en première ligne.


Antoine


Avatar
Jacques L'helgoualc'h
Le 28-06-2005, Antoine Leca a écrit :
Jacques L'helgoualc'h va escriure:
[1,/toto/ != 0,/toto/]
Et en dehors de la solution 0 de GNU (ce qui ne va pas être une amélioration
au niveau des performances), les autres manières de contourner ne me
plaisent pas du tout. :-(


Bah oui, une boucle avec GOTO n'est pas très lisible ...

Bon, si on prend en plus l'astuce de Laurent pour éviter le test pour d, on
obtient

gsed "0,/toto=/{ s|toto=||p; d; }"


Pas sûr que ça accélère, d'après sed1line.txt

,----
| sed 's/foo/bar/g' filename # standard replace command
| sed '/foo/ s/foo/bar/g' filename # executes more quickly
`----

on peut donc tester

gsed '0,/toto=/{/toto=/s/toto=//p;d;}'

ou

gsed '0,/toto=/{/toto=/!d;s/toto=//;}'


ou

sed "1,/toto=/{ s|toto=||p; d; }"

si toto= ne peut pas être en première ligne.


C'est ce que suggère la demande originale.
--
Jacques L'helgoualc'h

1 2