uso de alternância “|” no regex de sed

76

Eu estou usando sed, GNU sed versão 4.2.1. Eu quero usar a alternância "|" símbolo em uma subexpressão. Por exemplo :

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

deve retornar

" blib bou "

mas retorna

"blia blib bou blf".

Como posso ter o resultado esperado?

Cedric
fonte

Respostas:

109

O "|" também precisa de uma barra invertida para obter seu significado especial.

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

vai fazer o que quiser.

Como você sabe, se tudo mais falhar, leia o manual :-).

Manual do usuário do GNU sed , seção 3.3 Visão geral da sintaxe da expressão regular :

`REGEXP1 \ | REGEXP2 '

Corresponde a REGEXP1 ou a REGEXP2.

Observe a barra invertida ...

Infelizmente, a sintaxe de regex não é realmente padronizada ... há muitas variantes, que diferem entre outras coisas nas quais "caracteres especiais" precisam \ e quais não. Em alguns, é até mesmo configurável ou depende de switches (como no GNU grep, que você pode alternar entre três diferentes dialetos regex).

Esta resposta em particular é para o GNU sed . Existem outras sedvariantes, por exemplo, a usada nos BSDs, que se comportam de maneira diferente.

scho
fonte
35
Para mais alguém confuso com esta resposta \ | só funciona no gnu sed (gsed no os x) não baunilha sed (sed on os x).
Andrew Hancox
@AndrewHancox Muito obrigado! Eu estava prestes a arrancar todos os cabelos da minha cabeça (e até agora estou indo muito bem comparado ao meu empresário na frente do cabelo) - Eu sei que conheço o RegEx o suficiente para tentar | e \ | mas eu nunca pensei sobre o fato de que o OSX pode realmente usar um não-gnu sed.
phatskat 01 de
8
A versão padrão do BSD / OS X sedsuporta alternância, mas apenas com a sintaxe regex "estendida" ( -E) - o que significa que não há barras invertidas nos tubos ou nos parênteses:echo "blia blib bou blf" | sed -E 's/bl(ia|f)//g'
Mark Reed
2
Eu editei minha resposta para notar que é apenas para o GNU sed.
sleske
22

Já que existem vários comentários sobre sedimplementações não-Gnu : Pelo menos no OS X, você pode usar o -Eargumento para  sed:

Interpretar expressões regulares como expressões regulares estendidas (modernas) em vez de expressões regulares básicas (BREs). A página de manual re_format (7) descreve os dois formatos.

Então você pode usar metacaracteres de expressões regulares sem escapar deles. Exemplo:

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

O GNU sed também suporta a -ropção (expressões regulares estendidas). Isso significa que você não precisa escapar dos metacaracteres:

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

Saída:

hi hi
jco
fonte
Sim, a -ropção é realmente muito útil para a legibilidade das expressões. Essa deveria ser a resposta aceita.
руффп
9

O \|não funciona com sed no Solaris 10 também. O que eu fiz foi usar

perl -p -e 's/bl(ia|f)//g'
Joe Tennies
fonte
2
+1 para portabilidade, pois, se um sistema tiver perl, ele sempre usará essa sintaxe, diferente de sed.
Evilsoup
4

Acompanhamento: sed -E permite no MacOS. Não há necessidade de backslash para |.

 sed -E 's/this|orthat/oooo/g' infile
algumas ideias
fonte
1

No GnuWin32 no Windows sed a sintaxe é sed "s/thing1\|thing2/ /g" source > destination.

As aspas devem digitar "- isso é "Obrigatório" para o comando ser analisado.

twobob
fonte