我有一些脚本,产生输出的颜色,我需要删除ANSI代码。

#!/bin/bash

exec > >(tee log)   # redirect the output to a file but keep it on stdout
exec 2>&1

./somescript

输出为(在日志文件中):

java (pid  12321) is running...@[60G[@[0;32m  OK  @[0;39m]

我不知道如何在这里放置ESC字符,所以我把@放在它的位置。

我把剧本改成:

#!/bin/bash

exec > >(tee log)   # redirect the output to a file but keep it on stdout
exec 2>&1

./somescript | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"

但是现在它给了我(在日志文件中):

java (pid  12321) is running...@[60G[  OK  ]

我怎么也可以删除这个'@[60G?

也许有一种方法可以完全禁用整个脚本的着色?


当前回答

我无法从其他答案中得到满意的结果,但下面的答案对我来说很有用:

somescript | sed -r "s/[[:cntrl:]]\[[0-9]{1,3}m//g"

如果我只删除了控制字符“^[”,它就会留下其余的颜色数据,例如“33m”。加上颜色代码和“m”就成功了。我对s/\x1B//g不工作感到困惑,因为\x1B[31m当然可以与echo一起工作。

其他回答

我的贡献:

./somescript | sed -r "s/\\x1B[\\x5d\[]([0-9]{1,3}(;[0-9]{1,3})?(;[0-9]{1,3})?)?[mGK]?//g"

根据维基百科的说法,您正在使用的sed命令中的[m|K]是专门用于处理m(颜色命令)和K(“擦除行部分”命令)的。您的脚本试图将光标的绝对位置设置为60 (^[[60G),以获得一行中的所有ok,这是sed行没有覆盖的。

正确地,[m|K]应该是(m|K)或[mK],因为您并没有试图匹配一个管道字符。但现在这并不重要。)

如果您将命令中的最终匹配转换为[mGK]或(m|G|K),您应该能够捕获额外的控制序列。

./somescript | sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2};?)?)?[mGK]//g"

我也遇到过类似的问题。我发现的所有解决方案都适用于颜色代码,但没有删除“$(tput sgr0)”添加的字符(重置属性)。

以davemyron注释中的解决方案为例,在下面的例子中,结果字符串的长度是9,而不是6:

#!/usr/bin/env bash

string="$(tput setaf 9)foobar$(tput sgr0)"
string_sed="$( sed -r "s/\x1B\[[0-9;]*[JKmsu]//g" <<< "${string}" )"
echo ${#string_sed}

为了正常工作,regex必须扩展以匹配由sgr0 ("\E(B"))添加的序列:

string_sed="$( sed -r "s/\x1B(\[[0-9;]*[JKmsu]|\(B)//g" <<< "${string}" )"

有争议的想法是重新配置该进程环境的终端设置,让进程知道终端不支持颜色。

我想到了像TERM=xterm-mono ./somescript这样的东西。YMMV与您特定的操作系统和脚本理解终端颜色设置的能力。

Mac OSX或BSD使用

./somescript | sed $'s,\x1b\\[[0-9;]*[a-zA-Z],,g'