Question utilisation de l'alternance "|" dans l'expression reine


J'utilise sed, GNU sed version 4.2.1. Je veux utiliser l'alternance "|" symbole dans une sous-expression. Par exemple :

echo "blia blib bou blf" | sed 's/bl\(ia|f\)//g'

devrait retourner

" blib bou "

mais ça revient

"blia blib bou blf".

Comment puis-je obtenir le résultat attendu?


65
2018-02-22 14:31


origine




Réponses:


Le "|" a également besoin d'une barre oblique inverse pour obtenir sa signification particulière.

echo "blia blib bou blf" | sed 's/bl\(ia\|f\)//g'

fera ce que tu veux.

Comme vous le savez, si tout échoue, lisez le manuel :-).

Manuel de l'utilisateur GNU sed, section 3.3 Aperçu de la syntaxe des expressions régulières:

`REGEXP1 \ | REGEXP2 '

Correspond à REGEXP1 ou à REGEXP2.

Notez la barre oblique inverse ...

Malheureusement, la syntaxe regex n'est pas vraiment standardisée ... il y a beaucoup de variantes, qui diffèrent entre autres dans lesquelles "les caractères spéciaux" ont besoin \ et ceux qui ne le sont pas. Dans certains cas, il est même configurable ou dépend des commutateurs (comme dans GNU grep, que vous pouvez basculer entre trois dialectes de regex différents).

Cette réponse en particulier est pour GNU sed. Il y a d'autres sed variantes, par exemple celle utilisée dans les BSD, qui se comportent différemment.


97
2018-02-22 14:36



Pour toute autre personne confuse par cette réponse \ | ne fonctionne que dans gnu sed (gsed sur os x) pas vanille sed (sed sur os x). - Andrew Hancox
@AndrewHancox Merci beaucoup! J'étais sur le point de déchirer tous les cheveux de ma tête (et jusqu'à présent, je me débrouille plutôt bien par rapport à mon manager sur le front des cheveux) - Je sais que je connais assez RegEx pour essayer | et \ | mais je n'ai jamais pensé au fait qu'OSX pourrait utiliser un non-gnu sed. - phatskat
La version standard BSD / OS X de sed supporte l'alternance, mais seulement avec la syntaxe "étendue" de regex (-E) - ce qui signifie qu’il n’ya aucune barre oblique inverse sur les tubes ou les parenthèses: echo "blia blib bou blf" | sed -E 's/bl(ia|f)//g' - Mark Reed
J'ai édité ma réponse pour noter que c'est uniquement pour GNU sed. - sleske


Comme il y a plusieurs commentaires concernant les non-Gnu sed implémentations: au moins sous OS X, vous pouvez utiliser le -E argument àsed:

Interpréter les expressions régulières comme des expressions régulières étendues (modernes) plutôt que des expressions régulières de base (BRE). La page de manuel re_format (7) décrit complètement les deux formats.

Vous pouvez ensuite utiliser des métacaractères d'expression régulière sans les échapper. Exemple:

$ echo "blia blib bou blf" | sed -E 's/bl(ia|f)//g'
 blib bou 

17
2018-05-28 18:56





le \| ne fonctionne pas non plus avec sed sur Solaris 10. Ce que j'ai fait était d'utiliser

perl -p -e 's/bl(ia|f)//g'

9
2018-05-28 17:42



+1 pour la portabilité car, si un système a perl, il utilisera toujours cette syntaxe, contrairement à sed. - evilsoup


GNU sed supporte également le -r option (expressions régulières étendues). Cela signifie que vous n'avez pas à échapper aux métacaractères:

echo foohello barhello | sed -re "s/(foo|bar)hello/hi/g"

Sortie:

hi hi

9
2018-02-18 09:03



Oui, -r L'option est vraiment utile pour la lisibilité des expressions. Cela devrait être la réponse acceptée. - рüффп


Suivi: sed -E le permet sur MacOS. Pas besoin de backslash pour |.

 sed -E 's/this|orthat/oooo/g' infile

4
2017-08-28 20:15





Dans le GnuWin32 sur Windows sed, la syntaxe est sed "s/thing1\|thing2/ /g" source > destination.

Les citations doivent être de type " - ceci est "requis" pour que la commande soit analysée.


1
2018-02-18 04:19