为什么在我的sed命令中不能替换*字符?

时间:2020-04-30 17:23:20

标签: bash sed

我不明白为什么该命令:

echo "type    f(type     titi)" | sed 's/type\(\s+\)/void\1**/g'

输出以下内容:

type    f(type     titi)

我希望这样:

type    **f(type     **titi)

我试图在sed命令中转义*:

echo "type    f(type     titi)" | sed 's/type\(\s+\)/void\1\*\*/g'

但是输出保持不变。

2 个答案:

答案 0 :(得分:1)

问题不在于正则表达式的右侧被错误地解释,而是左侧根本不匹配。


BRE匹配,我们可以使用以下方法:

sed 's/type\([[:space:]]\{1,\}\)/void\1**/g'

请注意,\s已更改为[[:space:]],并且+已替换为符合标准的\{1,\}语法。 (对于sed的GNU版本,也可以在BRE中使用\+,但这是扩展,而不是标准规定的行为。)


或者,我们可以通过添加-r参数来切换到ERE,在这种情况下,我们不再需要在分组括号内使用反斜杠,并且可以保证+可以正常工作。

sed -re 's/type([[:space:]]+)/void\1**/g'

答案 1 :(得分:1)

sed 's/type\(\s+\)/void\1**/g'命令与type匹配,此后,它会将一个或多个空格字符匹配并放入一个组中,因为转义的圆括号在POSIX BRE中捕获了括号。

您所需要做的就是使用*(匹配0个或多个空格)而不是++匹配一个加号),或者-如果您必须至少匹配一个空格-\{1,\}

echo "type    f(type     titi)" | sed 's/type\(\s*\)/void\1**/g'

echo "type    f(type     titi)" | sed 's/type\(\s\{1,\}\)/void\1**/g'

两者都能给您预期的结果。