Usando sed con esta expresión regular:
message=$(echo "$path" | sed -E 's/(.+pattern[0-9][0-9]*).+/\1/')
Con esta expresión, líneas como esta:
/lol/pattern03657/qsd/qsd/pattern0001/qsd/
será reemplazado por:
/lol/pattern03657/qsd/qsd/pattern0001
mientras que me gustaría que fueran:
/lol/pattern03657/
Pensé que sed reemplazaría solo la primera aparición, pero parece que no lo hace. ¿Qué tengo que cambiar para que mi código se comporte de esta manera?
Respuesta1
Esto se debe a que *
son +
cuantificadores codiciosos, intentarán igualar tanto como sea posible.
$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | sed -E 's/(.+pattern[0-9][0-9]*).+/\1/'
/lol/pattern03657/qsd/qsd/pattern0001
perl
tiene un cuantificador no codicioso sumando ?
a+
$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | perl -pe 's/(.+?pattern\d+\/).+/\1/'
/lol/pattern03657/
o utilizar grep
con pcre
opción si está disponible
$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | grep -oP '^.+?pattern\d+/'
/lol/pattern03657/
Una solución alternativa sed
es saber dónde se produce la cadena. Por ejemplo:
$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | sed -E 's|^(/[^/]+/pattern[0-9][0-9]*/).+|\1|'
/lol/pattern03657/
Aquí, desde el inicio de la línea, un conjunto de /text/
precede a la cadena.