Verwenden von sed, um nur das erste Vorkommen des Musters zu ersetzen

Verwenden von sed, um nur das erste Vorkommen des Musters zu ersetzen

Verwenden von sed mit diesem regulären Ausdruck:

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

Mit diesem Ausdruck können Zeilen wie diese entstehen:

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

wird ersetzt durch:

/lol/pattern03657/qsd/qsd/pattern0001

Ich hätte sie gerne wie folgt:

/lol/pattern03657/

Ich dachte, sed würde nur das erste Vorkommen ersetzen, aber das scheint nicht der Fall zu sein. Was muss ich ändern, damit sich mein Code so verhält?

Antwort1

Das liegt daran *, dass +gierige Quantifizierer sind und versuchen werden, so viel wie möglich abzugleichen

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

perlhat einen nicht-gierigen Quantifizierer durch Hinzufügen ?zu+

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

grepoder mit Option verwenden pcre, falls verfügbar

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


Eine Problemumgehung sedbesteht darin, zu wissen, wo Ihre Zeichenfolge vorkommt. Beispiel:

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

Hier steht vom Zeilenanfang an ein Satz von /text/vor der Zeichenfolge

verwandte Informationen