sed 与 ANSI 颜色转义失败

sed 与 ANSI 颜色转义失败

我不知道为什么这不起作用:

echo -e "$(echo "This is an uncolored text" | sed "s/{This is an uncolored text}/{This is an \033[0;34uncolored text\033[0m}/g")"

但这样做效果很好:

echo "$(echo "Hello World" | sed "s/Hello/Hi/g")"

你能向我解释一下吗?

答案1

存在许多问题。

{...}首先, sed 表达式中的括号与输入中的任何内容都不匹配。在 sed 基本正则表达式中,括号是文字,而在扩展正则表达式中,它们围绕形式为 的量词{n,m}。它们从不用于分组。

其次,你的颜色序列是错误的 - 开头需要\033[0;34m而不是\033[0;34

第三,反斜杠字符\在 sed 中是特殊的 - 特别是,替换 RHS 上的反斜杠后跟十进制数字是对捕获组的反向引用;至少在 GNU sed 中,\0指的是整个捕获的 LHS,相当于特殊的替换标记,&例如

$ echo foo | sed 's/foo/\033bar/'
foo33bar

要将文字传递\到外部,echo -e您需要\\在 sed 替换字符串内部进行。

\最后,对 shell 来说很特殊,因此“软”双引号内需要额外的反斜杠。因此,要么:

echo -e "$(echo "This is an uncolored text" | 
  sed "s/This is an uncolored text/This is an \\\033[0;34muncolored text\\\033[0m/")"

或(将内部双引号替换为“strong”单引号):

echo -e "$(echo "This is an uncolored text" | 
  sed 's/This is an uncolored text/This is an \\033[0;34muncolored text\\033[0m/')"

请注意,您不需要使用g修饰符来对每行进行一次替换。

也可以看看在 sh 脚本中使用 sed 时需要转义哪些字符?

答案2

我制定的解决方案:

#!/bin/bash

colored_text='this is a \\033[0;34mtext\\033[0m'
uncolored_text='this is a text'

printf %b\\n "$(sed "s/$uncolored_text/$colored_text/" <<< "$uncolored_text")"

相关内容