usando sed para reemplazar solo la primera aparición del patrón

usando sed para reemplazar solo la primera aparición del patrón

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

perltiene un cuantificador no codicioso sumando ?a+

$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | perl -pe 's/(.+?pattern\d+\/).+/\1/'
/lol/pattern03657/

o utilizar grepcon pcreopción si está disponible

$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | grep -oP '^.+?pattern\d+/'
/lol/pattern03657/


Una solución alternativa sedes 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.

información relacionada