Eso es por razones históricas.
Regexp se introdujo por primera vez en Unix en la edutilidad a principios de los años 70. Aunque edse basa en qedcuya aplicación por parte de los mismos autores entendieron expresión regular más complejo, edsó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 edcomando s/foo() {/foo (var) {/gpara reemplazar todas las instancias de foo() {con foo(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 mismo s/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 el s edcomando haga cosas como s/foo\(.\)/\1bar/y luego como grep '\(.\)\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 egrepy las awkutilidades 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 Thompson qed(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, GNU awkhasta la versión 4.0.0 (2011) no era compatible a {menos que fuera forzado al modo de conformidad POSIX.
cuando GNU grepse 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 GNU grep(aunque eso no es POSIX o no es compatible con otras implementaciones) y puede hacerlo (.)\1en GNU egrep(aunque eso no es POSIX ni es compatible con muchas otras implementaciones, incluida GNU awk).
Agregar \xoperadores no es la única forma de agregar más operadores de una manera compatible con versiones anteriores. Por ejemplo, perlusado (?...). Eso sigue siendo compatible con versiones anteriores de ERE, ya (?=...)que no es válido en ERE, lo mismo para .*?. vimpara operadores similares lo hizo de manera diferente introduciendo \@=o .\{-}por ejemplo.