Debian-facile

Bienvenue sur Debian-Facile, site d'aide pour les nouveaux utilisateurs de Debian.

Vous n'êtes pas identifié(e).

#1 31-08-2020 14:17:29

David5647
Membre
Distrib. : Debian Bullseye/Sid
Noyau : 5.7.0-2-amd64
(G)UI : KDE/i3wm
Inscription : 27-08-2017

[astuce] sed vertueux : la gourmandise (non-greedy search pattern)

Partage d'une petite astuce avec sed (et autres commandes à regex)

Imaginons un texte dont je souhaite récupérer la première phrase :

Une 1ère phrase. Une deuxième phrase. Une troisième phrase. Une quatrième phrase!



L'idée semble simple à réaliser : je prends tout les caractères jusqu'au premier point inclu, soit le pattern : .*\.
Mais voilà, sed est gourmand, si l'on regarde ce que capture l’expression précédente :

echo "Une 1ère phrase. Une deuxième phrase. Une troisième phrase. Une quatrième phrase!" | sed -r 's/(.*\.).*/\1/'


Une 1ère phrase. Une deuxième phrase. Une troisième phrase.



Les diverses documentations semblent indiquer l’existence de symbole pour des "non-greedy pattern",
mais entre les différents types de regex et versions de sed, je n'ai rien trouvé de fonctionnel.

Donc voici la petite astuce : on prend tout les caractères sauf le point! C'est bête, mais fallait y penser!

echo "Une 1ère phrase. Une deuxième phrase. Une troisième phrase. Une quatrième phrase!" | sed -r 's/([^.]*\.).*/\1/'


Une 1ère phrase.



Et si je m'amuse à faire quelques itérations:

for i in 1 2 3; do echo "Une 1ère phrase. Une deuxième phrase. Une troisième phrase. Une quatrième phrase!" | sed -r "s/([^.]*\.){$i}.*/\1/" ; done


Une 1ère phrase.
 Une deuxième phrase.
 Une troisième phrase.



Voilà, c'est bête, mais j'ai cherché longtemps tongue

j'ai esquissé un tuto avec ça : https://debian-facile.org/atelier:chant … dy-pattern

Dernière modification par David5647 (31-08-2020 16:58:35)

Hors ligne

#2 07-09-2020 18:26:41

Beta-Pictoris
Membre
Lieu : Angers
Distrib. : Buster
Inscription : 11-08-2015

Re : [astuce] sed vertueux : la gourmandise (non-greedy search pattern)

Avec grep, on peut utiliser les opérateurs non gourmands (perl regex), sans avoir à faire des substitutions comme avec sed :

echo "Une 1ère phrase. Une deuxième phrase. Une troisième phrase. Une quatrième phrase!" | grep -Po '^.*?\.'

Dernière modification par Beta-Pictoris (07-09-2020 18:27:02)

Hors ligne

#3 07-09-2020 18:30:14

Beta-Pictoris
Membre
Lieu : Angers
Distrib. : Buster
Inscription : 11-08-2015

Re : [astuce] sed vertueux : la gourmandise (non-greedy search pattern)

Et avec perl, la regex doit être placée entre /( et )/

echo "Une 1ère phrase. Une deuxième phrase. Une troisième phrase. Une quatrième phrase!" | perl -ne 'print /(^.*?\.)/'

Dernière modification par Beta-Pictoris (07-09-2020 18:32:42)

Hors ligne

#4 08-09-2020 06:05:44

smolski
quasi...modo
Lieu : AIN
Distrib. : backports (buster) 10
Noyau : Linux 4.19.0-8-amd64
(G)UI : gnome
Inscription : 21-10-2008

Re : [astuce] sed vertueux : la gourmandise (non-greedy search pattern)

Merci !
Tuto mis en lien dans le tuto de sed :
https://debian-facile.org/doc:systeme:sed#lien wink

"Théo et Adama te rappellent pourquoi Zyed et Bouna couraient…"
"L'utopie ne signifie pas l'irréalisable, mais l'irréalisée." - T Monod (source :  La zone de Siné)
"Je peux rire de tout mais pas avec n'importe qui." - P Desproges
"saque eud dun" (patois chtimi : fonce dedans)

Hors ligne

#5 08-09-2020 07:10:01

captnfab
Admin-Girafe
Lieu : /dev/random
Distrib. : Debian
Noyau : Dur
(G)UI : gui gui, je zuis un doiseau
Inscription : 07-07-2008
Site Web

Re : [astuce] sed vertueux : la gourmandise (non-greedy search pattern)

Une autre solution amusante au problème :

echo 'Une 1ère phrase. Une deuxième phrase. Une troisième phrase. Une quatrième phrase !' | sed 's/\..*/./'


captnfab,
Association Debian-Facile, bépo.
TheDoctor: Your wish is my command… But be careful what you wish for.
Je suis parrain linux !

En ligne

#6 08-09-2020 22:20:54

Beta-Pictoris
Membre
Lieu : Angers
Distrib. : Buster
Inscription : 11-08-2015

Re : [astuce] sed vertueux : la gourmandise (non-greedy search pattern)

Oui, mais en perl, on peut extraire les 3 premières phrases individuellement. cthulhu.gifmrgreen.gif

echo 'Une 1ère phrase. Une deuxième phrase. Une troisième phrase. Une quatrième phrase !' | perl -ne 'print /^(.*?\.){0,1}/'

Une 1ère phrase.



echo 'Une 1ère phrase. Une deuxième phrase. Une troisième phrase. Une quatrième phrase !' | perl -ne 'print /^(.*?\.){0,2}/'

 Une deuxième phrase.



echo 'Une 1ère phrase. Une deuxième phrase. Une troisième phrase. Une quatrième phrase !' | perl -ne 'print /^(.*?\.){0,3}/'

 Une troisième phrase.

Hors ligne

#7 09-09-2020 08:30:01

David5647
Membre
Distrib. : Debian Bullseye/Sid
Noyau : 5.7.0-2-amd64
(G)UI : KDE/i3wm
Inscription : 27-08-2017

Re : [astuce] sed vertueux : la gourmandise (non-greedy search pattern)

@captnfab : Oui effectivement ^^, si c'est "greedy" d'un coté, c'est "non-greedy" de l'autre. Là encore c'est bête, mais il faut y penser!

@Beta-Pictoris : Conclusion : utiliser perl!!!! J'utilise généralement sed parce que j'ai commencé par là.
Je suppose que la plupart de mes recherches m'ont menées à sed. Visiblement perl permet des usages plus étendu.
Ai-je encore des raisons de lui préférer sed?

Hors ligne

#8 09-09-2020 18:38:14

Beta-Pictoris
Membre
Lieu : Angers
Distrib. : Buster
Inscription : 11-08-2015

Re : [astuce] sed vertueux : la gourmandise (non-greedy search pattern)

Perl est un vrai langage de programmation très complet. De plus, les regex perl sont très puissantes.

Beaucoup de langages à la mode, comme Python par exemple, utilisent les regex perl.

Cela dit, sed reste utile pour faire des chose plus simples.

Dernière modification par Beta-Pictoris (09-09-2020 21:46:19)

Hors ligne

Pied de page des forums