использование sed для замены только первого вхождения шаблона

использование sed для замены только первого вхождения шаблона

Используем sed с этим регулярным выражением:

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

С этим выражением получаются такие строки:

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

будет заменено на:

/lol/pattern03657/qsd/qsd/pattern0001

тогда как я хотел бы, чтобы они были:

/lol/pattern03657/

Я думал, что sed заменит только первое вхождение, но, похоже, этого не происходит. Что мне нужно изменить, чтобы мой код вел себя таким образом?

решение1

Это потому , что *, +являются жадными квантификаторами, будут пытаться сопоставить как можно больше

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

perlимеет нежадный квантификатор, добавляя ?к+

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

или используйте grepс pcreопцией, если доступно

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


Один из обходных путей sed— это если вы знаете, где находится ваша строка. Например:

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

Здесь, с начала строки, один набор /text/предшествует строке

Связанный контент