0%

转义sed替换模式字符串

本文记录了作者在使用sed命令进行文本替换时,对于使用到的替换模式进行转义处理使用到的sed命令,简单来说:

  • 使用sed -e 's/[]\/$*.^[]/\\&/g'即可对输入字符串进行转义

场景

sed命令常常被用来对文本做处理,其中一个最经常用到的处理就是替换,替换的语法如下:

1
echo $STRING | sed -e 's/<match_pattern>/<replace_pattern>/g'

当然也可以有其他的变化,不过这是作者使用的最多的方式。

在使用这些的时候,我们可能会在match_patternreplace_pattern中引用变量,已达到分别管理和增强可读性的目的,比如

1
2
3
4
# dummy text
TEXT="affaflns,fakfnakn"
REPLACE="ff"
REPLACED_TEXT=$(echo $TEXT | sed -e "s/a/$REPLACE/g")

但是,如果上面引用的REPLACE里面有特殊字符,我们就会遇到问题,比如

1
2
3
4
5
# dummy text
TEXT="affaflns,fakfnakn"
REPLACE="/a"
# 有问题
REPLACED_TEXT=$(echo $TEXT | sed -e "s/a/$REPLACE/g")

我们的本意是将a替换为/a,但是,使用这几条命令,会得到

1
2
sed: 1: "s/a//a/g
": bad flag in substitute command: 'a'

这里的原因就是/a中的/是一个特殊字符,如果希望得到我们上述的效果,应该这么操作

1
2
3
4
5
# dummy text
TEXT="affaflns,fakfnakn"
REPLACE="\/a"
# 成功
REPLACED_TEXT=$(echo $TEXT | sed -e "s/a/$REPLACE/g")

我们通过\/进行转义,取得了成功,但是这种方式使得我们编写replace_pattern变得麻烦,而且很不直观,我们希望有一个函数来达到如下效果

1
2
3
4
5
# dummy text
TEXT="affaflns,fakfnakn"
REPLACE="/a"
REPLACE=$(func $REPLACE)
REPLACED_TEXT=$(echo $TEXT | sed -e "s/a/$REPLACE/g")

也就是说,编写replace_pattern时,可以直接编写,而后使用一个函数或者命令自动转义再使用

解决方案

stackoverflow

使用sed -e 's/[]\/$*.^[]/\\&/g'即可

方案解析

我们这次的方案就是对原生的replace_pattern做一次替换:

  • match_pattern[]\/$*.^[]
    • 这个正则表达式的结构很具有迷惑性,其实它是一个大的bracket group
    • 也就是说,实际上是[ ]\/$*.^[ ]的结构
    • 意味着匹配]\/$*.^[中的任一字符
  • replace_pattern\\&
    • 这个replace_pattern用到了一个转义字符和一个特殊字符
    • 转义字符\\表示的就是\
    • 特殊字符&表示的是match_pattern匹配到的内容

综合起来,这个替换语句就是把]\/$*.^[前面全部加上一个斜杠,进行转义