
Tengo una cadena similar ../../sdd1
e intento hacer coincidir sdd
desde aquí. Estoy intentando utilizar el siguiente sed
comando:
echo "../../sdd1" | sed 's:.*\([a-z]\{3\}\)[0-9]?:\1:'
y no produce coincidencia.
Pero cuando uso
echo "../../sdd1" | sed 's:.*\([a-z]\{3\}\)[0-9]\{0,1\}:\1:'
entonces consigo mi pareja sdd
.
Mi mejor suposición es que también debería escapar del ?
, similar a las llaves: lo probé y funciona, pero no sé por qué.
Entonces la pregunta es, ¿por qué la [0-9]?
expresión regular no coincide con 1
from sdd1
o por qué tenemos que escapar de ?
y las llaves?
Respuesta1
De forma predeterminada, sed
usa BRE y necesitaría -E
una -r
opción para usar ERE
Citando demanual de sed gnu
En GNU sed, la única diferencia entre las expresiones regulares básicas y extendidas está en el comportamiento de algunos caracteres especiales: '?', '+', paréntesis, llaves ('{}') y '|'.
Con la sintaxis básica (BRE), estos caracteres no tienen un significado especial a menos que tengan el prefijo de barra invertida ('\'); Mientras que con la sintaxis extendida (ERE) se invierte: estos caracteres son especiales a menos que tengan el prefijo de barra invertida ('\').
entonces, para GNU sed
, usar
$ echo '../../sdd1' | sed 's:.*\([a-z]\{3\}\)[0-9]\?:\1:'
sdd
$ echo '../../sdd1' | sed -E 's:.*([a-z]{3})[0-9]?:\1:'
sdd
paraPOSIX BRE, tu segundo comando es el camino a seguir
$ echo '../../sdd1' | sed 's:.*\([a-z]\{3\}\)[0-9]\{0,1\}:\1:'
sdd