我有一些脚本,产生输出的颜色,我需要删除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?

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


当前回答

我有一些彩色输出的问题,其他解决方案在这里没有正确处理,所以我建立了这个perl一行。它查找转义\e,后面跟着开括号\[,后面跟着1或颜色代码\d+,以分号分隔,以m结尾。

perl -ple 's/\e\[\d+(;\d+)*m//g'

对于彩色编译器输出,它似乎工作得非常好。

其他回答

我在Debian的有色日志包中遇到了ansi2txt工具。该工具删除来自STDIN的ANSI控制代码。

使用的例子:

./somescript | ansi2txt

源代码http://github.com/kilobyte/colorized-logs

根据维基百科的说法,您正在使用的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"

不确定./somescript中有什么,但如果转义序列没有硬编码,您可以设置终端类型来避免它们

TERM=dumb ./somescript 

例如,如果你尝试

TERM=dumb tput sgr0 | xxd

您将看到它在while时没有输出

tput sgr0 | xxd
00000000: 1b28 421b 5b6d                           .(B.[m

Does(对于xterm-256color)。

嗯,不确定这是否为你工作,但'tr'将'剥离'(删除)控制代码-尝试:

./somescript | tr -d '[:cntrl:]'

@jeff-bowman的解决方案帮助我摆脱了一些颜色代码。 我在正则表达式中添加了另一小部分,以便删除更多:

sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" # Original. Removed Red ([31;40m[1m[error][0m)
sed -r "s/\x1B\[([0-9];)?([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" # With an addition, removed yellow and green ([1;33;40m[1m[warning][0m and [1;32;40m[1m[ok][0m)
                ^^^^^^^^^
                remove Yellow and Green (and maybe more colors)