如何在 BSD sed 上保持模式的一部分匹配并用它来替换?

如何在 BSD sed 上保持模式的一部分匹配并用它来替换?

我找到了 GNU sed 的灵魂,我也找到了类似的东西\1,但终端告诉我它“未在 RE 中定义”。

但我想做的是这样的:

如果我有一个看起来像这样的字符串sinder-city1.gif,我想这样做sinder-city.gif,现在我不能直接替换整个字符串,因为我将对许多不同的字符串执行此操作,也不能只删除 .gif 或之前的所有数字其他一些模式,因为如果有

sinder-city2.gif
sinder-city3.gif

我希望它们保持完好无损。

我不想更换它。为了匹配它,我输入,sed 's,[a-z]1.gif,但如果我删除它,我将留下sinder-cit.gif.我该如何匹配呢y

我想这样做:

sed 's,[a-z]1.gif,[here is the last letter].gif,g'

它必须在 BSD sed 上工作。

答案1

sed 's,\([a-z]\)1\.gif$,\1.gif,g'

或者,如果您想允许在1

sed 's,\([^0-9]\)1\.gif$,\1.gif,g'

反斜杠括号结构界定了一个捕获组,其中FreeBSD 手册页称为“括号表达式”(尽管使用了括号 - 方括号意味着其他含义)。请注意,sed 使用基本正则表达式 (BRE),而不是扩展正则表达式 (ERE);手册页描述了 ERE,最后一段解释了 BRE 语法和 ERE 语法之间的区别。我找到了POSIX规范比这里的 BSD 手册页更具可读性;它调用捕获组反向引用表达式。这GNU sed 手册比任何一个都更具可读性;只是避免被描述为 GNU 扩展的功能。

给定一个捕获组(也称为反向引用表达式),您可以在替换文本中使用反斜杠+数字来表示“与相应捕获组匹配的文本”。例如,\1替换文本中的文本将替换为正则表达式中第一个捕获组匹配的文本。这里有一个捕获组,它捕获 之前的字母1.gif

我改为1.gif1\.gif字面上匹配点,并添加尾随$以仅在行尾匹配。

举另一个捕获组的例子,如果你想对任意扩展进行操作,你可以使用类似的东西

sed 's,\([^0-9]\)1\(\.[^./]*\)$,\1\2,g'

相关内容