utilisation de l'alternance “|” dans l'expression rationnelle de sed

79

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

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

devrait revenir

" blib bou "

mais ça revient

"blia blib bou blf".

Comment puis-je avoir le résultat attendu?

Cedric
la source

Réponses:

110

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 vous voulez.

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

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

`REGEXP1 \ | REGEXP2 '

Correspond à REGEXP1 ou REGEXP2.

Notez le backslash ...

Malheureusement, la syntaxe des expressions rationnelles n’est pas vraiment normalisée ... Il existe de nombreuses variantes, qui diffèrent entre autres choses pour lesquelles les "caractères spéciaux" doivent \ et qui ne le sont pas. Dans certains cas, il est même configurable ou dépend de commutateurs (comme dans GNU grep, que vous pouvez basculer entre trois dialectes de regex différents).

Cette réponse en particulier s’applique à GNU sed . Il existe d'autres sedvariantes, par exemple celle utilisée dans les BSD, qui se comportent différemment.

sleske
la source
35
Pour toute autre personne déroutée 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 d'arracher tous les cheveux de ma tête (et jusqu'à présent, je me débrouille assez bien par rapport à mon manager sur le front des cheveux) - je sais que je connais suffisamment RegEx pour essayer | et \ | mais je n’ai jamais pensé au fait qu’OSX pourrait utiliser un logiciel non générique.
phatskat
8
La version standard BSD / OS X de sedprend en charge l’alternance, mais uniquement avec la syntaxe regex "étendue" ( -E), ce qui signifie qu’il n’ya pas de barre oblique inverse, ni sur les tubes ni entre parenthèses:echo "blia blib bou blf" | sed -E 's/bl(ia|f)//g'
Mark Reed le
2
J'ai modifié ma réponse pour noter que c'est uniquement pour GNU sed.
Sleske
23

Plusieurs remarques concernant les sedimplémentations non Gnu : Au moins sous OS X, vous pouvez utiliser l' -Eargument pour  sed:

Interprétez les expressions régulières comme des expressions régulières étendues (modernes) plutôt que comme 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 leur échapper. Exemple:

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

GNU sed supporte également l' -roption (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
jco
la source
Oui, l' -roption est vraiment très utile pour la lisibilité des expressions. Cela devrait être la réponse acceptée.
Vendredi
9

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

perl -p -e 's/bl(ia|f)//g'
Joe Tennies
la source
2
+1 pour la portabilité car, si un système est doté de Perl, il utilisera toujours cette syntaxe, contrairement à sed.
Evilsoup
4

Suivi: sed -E le permet sur MacOS. Pas de backslash nécessaire pour |.

 sed -E 's/this|orthat/oooo/g' infile
Quelques idées
la source
1

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

Les guillemets doivent être de type "- "Requis" pour que la commande soit analysée.

twobob
la source