简体   繁体   English

用sed内部bash进行简单替换不起作用

[英]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]/'
                       ^^

See this demo 这个演示

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM