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
perl
hat einen nicht-gierigen Quantifizierer durch Hinzufügen ?
zu+
$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | perl -pe 's/(.+?pattern\d+\/).+/\1/'
/lol/pattern03657/
grep
oder mit Option verwenden pcre
, falls verfügbar
$ echo '/lol/pattern03657/qsd/qsd/pattern0001/qsd/' | grep -oP '^.+?pattern\d+/'
/lol/pattern03657/
Eine Problemumgehung sed
besteht 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