Parece exemplo
cat sed_data.txt | sed 's/\b[0-9]\{3\}\b/NUMBER/g'
que eu deve escapar caracteres para formar uma expressão regular. Nesse caso, eu tive que escapar do aparelho para ser interpretado várias vezes.
Por quê? Eu esperava que tudo fosse um personagem regex, a menos que escapasse. Ou seja, o oposto.
11
s/regex//g
já espera uma regex e eu esperaria que fosse um texto que precisaria para escaparRespostas:
Isso ocorre porque
sed
usa BREs POSIX (Expressões regulares básicas) em oposição aos EREs (expressões regulares estendidas) às quais você provavelmente está acostumado a partir de Perl ou amigos.Na
sed(1)
página do manual:Citação relevante no link acima:
Citado literalmente no comentário de Craig Sanders :
fonte
-r
ou--regexp-extended
linha de comando. Isso é útil se você deseja evitar uglificar seu script sed com escape excessivo.sed
implementações (quando suportam EREs, principalmente BSDs) tendem a usar-E
para isso (o que faz muito mais sentido, já que é a mesma opção que paragrep
. Por que o GNUsed
escolheu-r
é um mistério para mim).Isso é por razões históricas.
O Regexp foi introduzido pela primeira vez no Unix no
ed
utilitário no início dos anos 70. Emboraed
foi baseada emqed
cuja implementação pelos mesmos autores entendido regexp mais complexo,ed
só entendeu^
,$
,[...]
,.
,*
e\
para escapar todos os itens acima.Agora, quando surgiu a necessidade de ter mais operadores, era necessário encontrar uma maneira de apresentá-los sem interromper a compatibilidade com versões anteriores. Se um script usado para usar o
s
ed
comando comos/foo() {/foo (var) {/g
para substituir todas as instânciasfoo() {
comfoo(var) {
e você introduziu um(
ou{
operador, que iria quebrar esse script.No entanto, nenhum script faria isso
s/foo\(\) {/foo\(var\) {/
, porque é o mesmos/foo() {/foo(var) {/
e não havia razão para escapar,(
pois esse não era um operador de ER. Portanto, a introdução de um operador novo\(
ou\{
não quebra a compatibilidade com versões anteriores, pois é muito improvável que ele interrompa um script existente usando a sintaxe mais antiga.Então, foi o que foi feito. Mais tarde,
\(...\)
foi adicionado inicialmente apenas para os
ed
comando fazer coisas comos/foo\(.\)/\1bar/
e mais tarde comogrep '\(.\)\1'
(mas ainda não coisas como\(xx\)*
).No UnixV7 (1979, quase uma década depois), uma nova forma de expressões regulares foi adicionada no novo
egrep
e osawk
utilitários chamados expressão regular estendida (por serem novas ferramentas, não há compatibilidade com versões anteriores a serem quebradas). Por fim, ele forneceu a funcionalidade disponível no antigo de Ken Thompsonqed
(operador de alternância|
, agrupamento(..)*
) e adicionou alguns operadores como+
e?
(mas não tinha o recurso de backref das expressões regulares básicas).Posteriormente, os BSDs adicionaram
\<
e\>
(para BRE e ERE) e o SysV adicionaram\{
e\}
somente para BREs.Não é até muito mais tarde do que o ERE
{
e}
foi adicionado ao ERE por essa compatibilidade com versões anteriores. Nem todo mundo adicionou. Por exemplo, o GNUawk
até a versão 4.0.0 (2011) não suportava, a{
menos que fosse forçado a entrar no modo de conformidade POSIX.quando GNU
grep
foi escrita no início dos anos 90, é adicionado todos os presentes de ambos BSD e SysV (como\<
,{
) e em vez de ter duas sintaxe expreg separada e motor para ERB e ERE, implementados os mesmos operadores em ambos, apenas os homólogos BRE de(
,?
,{
,+
tem que ser precedida por uma barra invertida (para ser compatível com outras implementações BRE). É por isso que você pode fazer.\+
no GNUgrep
(embora isso não seja POSIX ou suportado por outras implementações) e você pode fazer(.)\1
no GNUegrep
(embora isso não seja POSIX ou seja suportado por muitas outras implementações, incluindo o GNUawk
).Adicionar
\x
operadores não é a única maneira de adicionar mais operadores de maneira compatível com versões anteriores. Por exemplo,perl
usado(?...)
. Isso ainda é compatível com EREs, pois(?=...)
não é válido em EREs, o mesmo para.*?
.vim
para operadores semelhantes, diferentemente, introduzindo\@=
ou.\{-}
por exemplo.fonte