如何从变量中去除ANSI转义序列?

3
奇怪的问题。当我在Bash中设置一个变量以显示为特定颜色时,我不知道如何重置它。以下是一个示例:
首先定义颜色代码:
YELLOW=$(tput setaf 3)
RESET=$(tput sgr0)    

现在设置错误消息变量并将其颜色标识出来。
ERROR="File not found: "$YELLOW"Length.db$RESET"

这将把变量ERROR设置为函数返回的错误消息,最终在终端上显示。除文件名外,错误消息将全部为白色。为了让用户更容易看到,文件名会被突出显示为黄色。
这种方法非常有效,但在使用rsyslog进行日志记录时会出现问题。当错误消息被记录时,输出的内容如下所示:
File not found: #033[33mLength.db#033(B#033[m
这显然使日志文件非常难以阅读。起初我认为可以在输出到终端之前但在记录日志之前立即处理错误消息,但没有任何可搜索和替换的内容。也就是说,我认为可以使用sed来执行类似于以下操作的操作:
ERROR=$(echo "$ERROR" | sed -r 's%\#033\[33m%%')

但是当你打印变量时,这些字符不会出现(因为在终端上看不到它)。所以我陷入了困境。我不知道如何在设置变量后重置变量的颜色。我也尝试使用$RESET反转该过程,但可能我的语法有误或其他原因。

2个回答

3
你差点就做对了。试试这个吧:
ERROR=$(echo "$ERROR" | sed 's%\o033\[33m%%g')

请注意,使用sed中的\oNNN转义序列是GNU扩展,因此不符合POSIX标准。如果这是一个问题,你应该可以尝试做一些类似于以下的事情:
ERROR=$(echo "$ERROR" | sed 's%'$(echo -en "\033")'\[33m%%g')

显然,这只适用于特定颜色(黄色),要删除任何转义序列的正则表达式(例如其他颜色、背景颜色、光标定位等)会比较复杂

另外请注意,由于这里没有使用扩展正则表达式语法,因此不需要使用-r。我猜你已经知道了这一点,并且你只是出于惯例包含了-r,但出于清晰起见,我还是提一下。


1
这是一个纯Bash解决方案:

ERROR="${ERROR//$'\e'\[*([0-9;])m/}"

将其转换为函数:
# Strips ANSI codes from text
# 1: The text
# >: The ANSI stripped text
function strip_ansi() {
  shopt -s extglob # function uses extended globbing
  printf %s "${1//$'\e'\[*([0-9;])m/}"
}

请参见:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接