使用 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/字符串之前

相关内容