uso de alternancia "|" en la expresión regular de sed

79

Estoy usando sed, GNU sed versión 4.2.1. Quiero usar la alternancia "|" símbolo en una subexpresión. Por ejemplo :

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

debería volver

" blib bou "

pero vuelve

"blia blib bou blf".

¿Cómo puedo obtener el resultado esperado?

Cedric
fuente

Respuestas:

110

El "|" También necesita una barra invertida para obtener su significado especial.

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

Hará lo que quieras.

Como sabes, si todo lo demás falla, lee el manual :-).

Manual del usuario de GNU sed , sección 3.3 Descripción general de la sintaxis de expresión regular :

`REGEXP1 \ | REGEXP2 '

Coincide ya sea REGEXP1 o REGEXP2.

Tenga en cuenta la barra invertida ...

Desafortunadamente, la sintaxis de expresiones regulares no está realmente estandarizada ... hay muchas variantes, que difieren entre otras cosas en las que los "caracteres especiales" necesitan \ y los que no. En algunos incluso es configurable o depende de interruptores (como en GNU grep, que puede cambiar entre tres dialectos de expresiones regulares diferentes).

Esta respuesta en particular es para GNU sed . Hay otras sedvariantes, por ejemplo, la utilizada en los BSD, que se comportan de manera diferente.

sleske
fuente
35
Para cualquier otra persona confundida por esta respuesta \ | solo funciona en gnu sed (gsed en os x) no en vainilla sed (sed en os x).
Andrew Hancox
@ AndrewHancox ¡Muchas gracias! Estaba a punto de arrancarme todo el cabello de la cabeza (y hasta ahora lo estoy haciendo bastante bien en comparación con mi gerente en el frente del cabello). Sé que conozco lo suficiente RegEx como para intentarlo | y \ | pero nunca pensé en el hecho de que OSX en realidad podría usar un no gnu sed.
Phatskat 01 de
8
La versión estándar de BSD / OS X sedadmite alternancia, pero solo con sintaxis de expresiones regulares "extendida" ( -E), lo que significa que no hay barras invertidas ni en las tuberías ni en los paréntesis:echo "blia blib bou blf" | sed -E 's/bl(ia|f)//g'
Mark Reed
2
Edité mi respuesta para notar que es solo para GNU sed.
sleske
23

Dado que hay varios comentarios con respecto a sedimplementaciones que no son Gnu : al menos en OS X, puede usar el -Eargumento para  sed:

Interprete las expresiones regulares como expresiones regulares extendidas (modernas) en lugar de expresiones regulares básicas (BRE). La página del manual re_format (7) describe completamente ambos formatos.

Luego puede usar metacaracteres de expresión regular sin escapar de ellos. Ejemplo:

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

GNU sed también admite la -ropción (expresiones regulares extendidas). Esto significa que no tiene que escapar de los metacaracteres:

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

Salida:

hi hi
jco
fuente
Sí, la -ropción es realmente muy útil para la legibilidad de las expresiones. Esa debería ser la respuesta aceptada.
рüффп
9

El \|no funciona con sed en Solaris 10 tampoco. Lo que hice fue usar

perl -p -e 's/bl(ia|f)//g'
Joe Tennies
fuente
2
+1 para portabilidad ya que, si un sistema tiene perl, siempre usará esta sintaxis, a diferencia de sed.
evilsoup
4

Seguimiento: sed -E lo permite en MacOS. No necesita barra invertida para |.

 sed -E 's/this|orthat/oooo/g' infile
algunas ideas
fuente
1

En GnuWin32 en Windows sed, la sintaxis es sed "s/thing1\|thing2/ /g" source > destination.

Las comillas deben ser de tipo ": esto es "Obligatorio" para que se analice el comando.

dos bobos
fuente