sed 中的正则表达式

Posted

技术标签:

【中文标题】sed 中的正则表达式【英文标题】:regex in sed 【发布时间】:2010-09-19 02:04:33 【问题描述】:

我需要使用 sed 将所有出现的 ##XXX## 转换为 $XXX。 X 可以是任何字母字符或“_”。我知道我需要使用类似的东西:

's/##/\$/g'

但这当然不会正确,因为它会将 ##FOO## 转换为 $FOO$

有接受者吗? - 唐

【问题讨论】:

【参考方案1】:

这里有一个更好的替换正则表达式:

's/##\([a-zA-Z_]\+\)##/$\1/g'

或者如果你假设恰好三个字符:

's/##\([a-zA-Z_]\3\\)##/$\1/g'

【讨论】:

【参考方案2】: 将 alpha 和 '_' 封装在 '\(' 和 '\)' 中,然后在右侧使用 '\1' 引用它。 '+' 匹配一个或多个 alpha 和 '_'(如果您看到 ####)。 在末尾添加“g”选项以替换所有匹配项(我猜这就是您在这种情况下想要执行的操作)。
的/##\([a-zA-Z_]\+\)##/$\1/g'

【讨论】:

+ 不是 sed 中的标准运算符 -- 可能在 GNU sed 中。 没有提到数字。 是的,+ 是 GNU sed 中的一个运算符,可能不是。【参考方案3】:

使用这个:

s/##\([^#]*\)##/$\1/

顺便说一句,“s”运算符右侧的 $ 不需要转义。

【讨论】:

[^#] 不是“任何字母字符或'_'”字符串的准确匹配。【参考方案4】:
sed 's/##\([a-zA-Z_][a-zA-Z_][a-zA-Z_]\)##/$\1/'

\(...\) 记住...并在扩展中被称为\1。使用单引号来保持理智。

正如下面的 cmets 所述,这也可以收缩为:

sed 's/##\([a-zA-Z_]\3\\)##/$\1/'

此答案假定该示例需要精确匹配三个字符。根据哈希标记之间的内容,有多种变化。关键部分是记住匹配字符串的一部分。

【讨论】:

您假设井号之间正好有三个字符。即便如此,您也可以通过将 [a-zA-Z_][a-zA-Z_][a-zA-Z_] 转换为 [a-zA-Z_]3 来折叠它。 这个问题只要求 3 'X';我同意这之间的字符是否可以在数量上是可变的会更清楚。【参考方案5】:
echo "##foo##" | sed 's/##/$/;s///'
s 默认只修改 1 次 s//take 最后使用的搜索模式,所以 second s 也采取 ## 并且只有第二个出现仍然存在

【讨论】:

【参考方案6】:

回显'##XXX##' | sed "s/^##([^#]*)/##$\1/g"

【讨论】:

回显'##XXX##' | sed "s/^##([^#]*)/##$\\1\/g"【参考方案7】:

sed 's/([^a-z][^A-Z][^0-9]*)/(&)/pg

【讨论】:

这是错误的。它没有给出他所期望的有效答案。仔细阅读问题。

以上是关于sed 中的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

对于Linux正则表达式在sed awk 过滤中的深入浅出

在 sed 中使用反向引用正则表达式

sed正则表达式中的布尔OR

shell中的SED与正则式(帮我做下这些题目,谢谢)

Shell编程之正则表达式(sed)

正则表达式学习之grep,sed和awk