[英]Simple replacement with sed inside bash not working
Why is this simple replacement with sed
inside bash
not working? 为什么用
bash
内的sed
这种简单替换无法正常工作?
echo '[a](!)' | sed 's/[a](!)/[a]/'
It returns [a](!)
instead of [a]
. 它返回
[a](!)
而不是[a]
。 But why, given that only three characters need to be escaped in a sed
replacement string? 但是,为什么在
sed
替换字符串中只需要转义三个字符呢?
If I account for the case that additional characters need to be replaced in the regex string and try 如果我考虑到需要在正则表达式字符串中替换其他字符的情况,然后尝试
echo '[a](!)' | sed 's/\[a\]\(!\)/[a]/'
it is still not working. 它仍然无法正常工作。
The point is that [a]
in the regex pattern does not match square brackets that form a bracket expression . 关键在于,
[a]
在正则表达式模式不匹配方括号形成括号表达式 。 Escape the first [
for it to be parsed as a literal [
symbol, and your replacement will work: 转义第一个
[
以便将其解析为文字[
符号,然后您的替换将起作用:
echo '[a](!)' | sed 's/\[a](!)/[a]/'
^^
sed uses BREs by default and EREs can be enabled by escaping individual ERE metacharaters or by using the -E
argument. sed默认情况下使用BRE,并且可以通过转义各个ERE元字符或使用
-E
参数来启用ERE。 [
and ]
are BRE metacharacters, (
and )
are ERE metacharacters. [
和]
是BRE元字符, (
和)
是ERE元字符。 When you wrote: 当你写:
echo '[a](!)' | sed 's/\[a\]\(!\)/[a]/'
you were turning the [
and ]
BRE metacharacters into literals, which is good, but you were turning the literal (
and )
into ERE metacharacters, which is bad. 您将
[
和]
BRE元字符转换为文字,这是很好的,但是您正在将文字(
和)
转换为ERE元字符,这是不好的。 This is what you were trying to do: 这是您要尝试执行的操作:
echo '[a](!)' | sed 's/\[a\](!)/[a]/'
which you'd probably really want to write using a capture group: 您可能真的想使用捕获组编写该代码:
echo '[a](!)' | sed 's/\(\[a\]\)(!)/\1/'
to avoid duplicating [a]
on both sides of the substitution. 避免在替换的两面重复
[a]
。 With EREs enabled using the -E
argument that last would be: 使用
-E
参数启用ERE后,最后是:
echo '[a](!)' | sed -E 's/(\[a\])\(!\)/\1/'
Read the sed man page and a regexp tutorial. 阅读sed手册页和regexp教程。
man echo
tells that the command echo
display a line of text. man echo
告诉命令echo
显示一行文本。 So [
and (
with their closing brackets are just text. 因此
[
和(
及其右括号只是文本。
If you read man grep
and type there /^\\ *Character Classes and Bracket Expressions
and /^\\ *Basic vs Extended Regular Expressions
you can read the difference. 如果您阅读
man grep
并在其中输入/^\\ *Character Classes and Bracket Expressions
以及/^\\ *Basic vs Extended Regular Expressions
,则可以读取差异。 sed and other tools that use regex interprets this as Character Classes and Bracket Expressions. sed和其他使用正则表达式的工具将其解释为字符类和括号表达式。
You can try this 你可以试试这个
$ echo '[a](!)' | sed 's/(!)//'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.