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
perl
tem um quantificador não ganancioso adicionando ?
a+
$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | perl -pe 's/(.+?pattern\d+\/).+/\1/'
/lol/pattern03657/
ou use grep
com pcre
opçã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