grep
e sed
ambos são descritos como usando "regex básico" ("BRE") por padrão. BRE está bem descrito aqui .
Mas considere esta saÃda:
# echo ' aaaaa ' | grep '\(aaaaa\|bbbbb\)'
aaaaa
# echo ' aaaaa ' | sed '/\(aaaaa\|bbbbb\)/ s/ /_/g'
aaaaa
No primeiro comando, a \( ... \| ... \)
sintaxe agia claramente como (X OR Y)
, já que a saÃda passou grep
.
No segundo comando, a \( ... \| ... \)
sintaxe claramente não agiu como (X OR Y)
, porque os espaços não foram alterados para sublinhados.
(Em contraste, ambos os comandos reconhecem \+
como "uma ou mais repetições")
O que aconteceu? Por que parece haver dois tipos de BRE no FreeBSD, um dos quais reconhece a sintaxe que o outro não?
A questão mais profunda é que muitos projetos procuram o BRE para fornecer portabilidade para outros sistemas do tipo unix. Mas isso sugere que mesmo os BREs provavelmente não serão os mesmos em todas as plataformas, se eles não puderem ser os mesmos em plataformas individuais. Argh?
A descrição no artigo vinculado está errada.
A definição real do POSIX afirma que:
E caracteres comuns são definidos como quaisquer, exceto os caracteres especiais BRE
.[^$*
e a própria barra invertida.Portanto, ao contrário das reivindicações da página, o
\+
é indefinido no BRE e o\|
.Algumas implementações de regex as definem como o mesmo que ERE
+
e|
, no entanto, particularmente as GNU. Mas você não deve contar com isso, atenha-se aos recursos definidos.O problema aqui, é claro, é que o operador de alternância ERE
|
não existe em BRE, e o equivalente a ERE+
é terrivelmente feio (é\{1,\}
). Então você provavelmente quer usar o ERE.or
não é um BRE (Expressão Regular Básica). Você precisa especificar-E
para BRE estendido .Veja alternação/ou operador Regex (foo|bar) em GNU ou BSD Sed
ATUALIZAR
Por que o grep funcionou?
Podemos escolher que tipo de padrão queremos usar com grep
Ao usar essas opções, podemos ver que
grep
o padrão é BRE e que a expressão OP falha com ERE:Tanto o grep quanto o sed fazem referência ao re_format (7) que afirma claramente:
Mas parece que, se "escaparmos do cano", de fato obteremos a funcionalidade. Isso certamente tem um cheiro. Além disso, parece haver uma quebra recente nesse estádio - veja regex(3): Adicionar teste para cobrir a regressão BRE recente .
E parece haver algum trabalho para substituir o regex na libc.
Como Charles Duffy comenta abaixo
Estou acostumado a uma documentação muito boa com o FreeBSD. Isso significa que não tenho certeza se isso é intencional, mas não documentado - ou quebra.