我找到了 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.gif
从1\.gif
字面上匹配点,并添加尾随$
以仅在行尾匹配。
举另一个捕获组的例子,如果你想对任意扩展进行操作,你可以使用类似的东西
sed 's,\([^0-9]\)1\(\.[^./]*\)$,\1\2,g'