Parece, por ejemplo,
cat sed_data.txt | sed 's/\b[0-9]\{3\}\b/NUMBER/g'
que debo escapar de los caracteres para formar una expresión regular. En este caso, tuve que escapar de las llaves para ser interpretado varias veces.
¿Por qué? Esperaba que todo fuera un personaje regex a menos que escapara. Es decir, lo contrario.
11
s/regex//g
ya espera una expresión regular y esperaría que sea texto que necesitaría para escaparRespuestas:
Esto se debe a que
sed
utiliza BRE de POSIX (expresiones regulares básicas) en lugar de las ERE (expresiones regulares extendidas) a las que probablemente esté acostumbrado por Perl o sus amigos.Desde la
sed(1)
página del manual:Cita relevante del enlace de arriba:
Citado textualmente del comentario de Craig Sanders :
fuente
-r
o--regexp-extended
. Esto es útil si desea evitar uglificar su script sed con un escape excesivo.sed
implementaciones (cuando admiten ERE, en su mayoría BSD) tienden a usar-E
para eso en su lugar (lo que tiene mucho más sentido ya que esa es la misma opción que paragrep
. Por qué GNUsed
eligió-r
es un misterio para mí).Eso es por razones históricas.
Regexp se introdujo por primera vez en Unix en la
ed
utilidad a principios de los años 70. Aunqueed
se basa enqed
cuya aplicación por parte de los mismos autores entendieron expresión regular más complejo,ed
sólo se entiende^
,$
,[...]
,.
,*
y\
para escapar de todo lo anterior.Ahora, cuando surgió la necesidad de tener más operadores, se tuvo que encontrar una manera de introducirlos sin romper la compatibilidad con versiones anteriores. Si un script solía usar el
s
ed
comandos/foo() {/foo (var) {/g
para reemplazar todas las instancias defoo() {
confoo(var) {
y usted introdujo un operador(
u{
, eso rompería ese script.Sin embargo, ningún script funcionaría
s/foo\(\) {/foo\(var\) {/
, porque es lo mismos/foo() {/foo(var) {/
y no había razón para escapar(
ya que no era un operador RE. Por lo tanto, la introducción de un operador nuevo\(
o\{
no rompe la compatibilidad con versiones anteriores, ya que es muy poco probable que rompa un script existente utilizando la sintaxis anterior.Entonces, eso fue lo que se hizo. Más tarde,
\(...\)
se agregó inicialmente solo para que els
ed
comando haga cosas comos/foo\(.\)/\1bar/
y luego comogrep '\(.\)\1'
(pero aún no cosas como\(xx\)*
).En UnixV7 (1979, casi una década después), se agregó una nueva forma de expresiones regulares en las nuevas
egrep
y lasawk
utilidades llamadas expresiones regulares extendidas (dado que son nuevas herramientas, no hay compatibilidad con versiones anteriores que se rompan). Finalmente, proporcionó la funcionalidad disponible en el antiguo Ken Thompsonqed
(operador de alternancia|
, agrupación(..)*
) y agregó algunos operadores como+
y?
(pero no tenía la función de reflujo de las expresiones regulares básicas).Más tarde, se agregaron BSD
\<
y\>
(tanto a BRE como a ERE), y SysV se agregó\{
y\}
solo a BRE.No es hasta mucho más tarde
{
y}
se agregaron a ERE, al romper la compatibilidad con versiones anteriores. No todos lo agregaron. Por ejemplo, GNUawk
hasta la versión 4.0.0 (2011) no era compatible a{
menos que fuera forzado al modo de conformidad POSIX.cuando GNU
grep
se escribió a principios de los 90, agregó todas las ventajas de BSD y SysV (como\<
,{
) , y en lugar de tener dos sintaxis regexp y un motor separados para BRE y ERE, implementó los mismos operadores en ambos, solo los equivalentes BRE de(
,?
,{
,+
tiene que ser precedido por una barra invertida (para que sea compatible con otras implementaciones BRE). Es por eso que puede hacerlo.\+
en GNUgrep
(aunque eso no es POSIX o no es compatible con otras implementaciones) y puede hacerlo(.)\1
en GNUegrep
(aunque eso no es POSIX ni es compatible con muchas otras implementaciones, incluida GNUawk
).Agregar
\x
operadores no es la única forma de agregar más operadores de una manera compatible con versiones anteriores. Por ejemplo,perl
usado(?...)
. Eso sigue siendo compatible con versiones anteriores de ERE, ya(?=...)
que no es válido en ERE, lo mismo para.*?
.vim
para operadores similares lo hizo de manera diferente introduciendo\@=
o.\{-}
por ejemplo.fuente