usando sed para substituir apenas a primeira ocorrência do padrão

usando sed para substituir apenas a primeira ocorrência do padrão

Usando sed com esta expressão regular:

message=$(echo "$path" | sed -E 's/(.+pattern[0-9][0-9]*).+/\1/')

Com esta expressão, linhas como esta:

/lol/pattern03657/qsd/qsd/pattern0001/qsd/

será substituído por:

/lol/pattern03657/qsd/qsd/pattern0001

enquanto eu gostaria que eles fossem:

/lol/pattern03657/

Achei que sed substituiria apenas a primeira ocorrência, mas parece que não. O que preciso mudar para que meu código se comporte dessa maneira?

Responder1

Isso porque *, +são quantificadores gananciosos, tentarão igualar o máximo possível

$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | sed -E 's/(.+pattern[0-9][0-9]*).+/\1/'
/lol/pattern03657/qsd/qsd/pattern0001

perltem um quantificador não ganancioso adicionando ?a+

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

ou use grepcom pcreopção, se disponível

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


Uma solução alternativa sedé saber onde sua string ocorre. Por exemplo:

$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | sed -E 's|^(/[^/]+/pattern[0-9][0-9]*/).+|\1|'
/lol/pattern03657/

Aqui, desde o início da linha, um conjunto /text/precede a string

informação relacionada