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

1

Usando o sed com essa expressão regular:

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

Com esta expressão, linhas como esta:

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

será substituído por:

/lol/pattern03657/qsd/qsd/pattern0001

considerando que eu gostaria que eles fossem:

/lol/pattern03657/

Eu pensei que o sed iria substituir apenas a primeira ocorrência, mas parece que isso não acontece. O que preciso alterar para que meu código se comporte dessa maneira?

    
por aze 28.09.2016 / 11:43

1 resposta

2

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

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

perl tem um quantificador não-ágil adicionando ? a +

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

ou use a opção grep com pcre , se disponível

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


Uma solução alternativa com sed é se você souber onde sua string ocorre. Por ex:

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

Aqui, a partir do início da linha, um conjunto de /text/ precede a string

    
por 28.09.2016 / 11:46

Tags