我想sed
用来转义变量中包含的字符串中所有未转义的字符,比如“&” text
。我所做的是
text='one&two\&three'
sed 's/\([^\\]\)&/\1\\&/g' <<< "${text}"
我希望输出是one\&two\&three
. 但是,我得到的是
one\e&two\&three
我(尝试)做什么:
- 搜索模式
\([^\\]\)&
应该匹配&
前面没有反斜杠的任何出现,并将前面的字符存储&
在\1
- 替换模式
\1\\&
应该在和前一个字符之间放一个反斜杠,但是出于某种奇怪的原因&
它的行为\\\1&
我在这里做错了什么?
为什么您的命令失败:
你做了:
[^\\]\
匹配除 之外的任何字符\
,并将其放入匹配组 1,然后&
匹配文字&
。所以 forone&two\&three
, this 将匹配e
before first&
, 把它放在捕获的组 1 中。 For the&
beforethree
this 不会像\
以前一样匹配&
在您使用的替换中
\1\\&
,因此输出变为one\e&two\&three
:\1
被替换为e
\\
s 被视为 single\
。这给了我们e\
直到现在&
将匹配完整匹配,即e&
不会&
像您想的那样被转义因此,匹配的部分 ie
e&
被替换为e\e&
如果您
\
之前使用过另一个,您将获得所需的结果&
(因为两个\\
使一个\
,所以您之前&
也需要一个:由于 Ubuntu
sed
支持 ERE(扩展正则表达式),您可以使用-E
or -选项来启用它以在捕获时r
摆脱s:()
替代方法:
首先,
\
在所有 s 之前删除 s&
,然后\
在 all 之前添加&
:这由两个
sed
语句组成:s/[\]+(&)/\1/g
删除字符串(行)中\
之前的所有 s&
s/&/\\&/g
在字符串(行)中添加了一个\
too all&
例子: