从文本流中删除ANSI颜色代码


73

检查来自的输出

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";'

在文本编辑器(例如vi)中显示以下内容:

^[[37mABC
^[[0m

如何从输出文件中删除ANSI颜色代码?我想最好的方法是通过各种流编辑器通过管道传递输出。

以下不起作用

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' | perl -pe 's/\^\[\[37m//g' | perl -pe 's/\^\[\[0m//g'

这不是问题的答案,但您也可以通过管道将输出传递到moreless -R可以将转义码解释为颜色,而不是使用文本编辑器。
terdon

Answers:


97

字符^[[37m^[[0mANSI转义序列(CSI代码)的一部分。另请参阅这些规格

使用GNU sed

sed 's/\x1b\[[0-9;]*m//g'
  • \x1b(或\x1B)是转义特殊字符
    sed不支持替代字符\e\033
  • \[ 是转义序列的第二个字符
  • [0-9;]* 是颜色值正则表达式
  • m 是转义序列的最后一个字符

mac在macOS上,默认sed命令不支持特殊字符,例如slmsteamer25在注释中\e指出的字符。使用代替,您可以使用安装。gsedbrew install gnu-sed

OP命令行示例:   (OP表示原始海报)

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' | 
      sed 's/\x1b\[[0-9;]*m//g'

汤姆·黑尔Tom Hale)建议删除所有其他转义序列,[a-zA-Z]而不仅仅是使用m图形模式(彩色)转义序列专用的字母。但是[a-zA-Z]可能太宽了,可能会去除太多。MichałFaleńskiMiguel Mota建议分别使用[mGKH]和删除一些转义序列[mGKF]Britton Kerin指出K,除了mgcc错误/警告中删除颜色之外,还必须使用(不要忘记重定向gcc 2>&1 | sed...)。

sed 's/\x1b\[[0-9;]*m//g'           # Remove color sequences only
sed 's/\x1b\[[0-9;]*[a-zA-Z]//g'    # Remove all escape sequences
sed 's/\x1b\[[0-9;]*[mGKH]//g'      # Remove color and move sequences
sed 's/\x1b\[[0-9;]*[mGKF]//g'      # Remove color and move sequences
Last escape
sequence
character   Purpose
---------   -------------------------------
m           Graphics Rendition Mode (including Color)
G           Horizontal cursor move
K           Horizontal deletion
H           New cursor position
F           Move cursor to previous n lines

使用 perl

sed在某些操作系统上安装的版本可能受到限制(例如macOS)。该命令perl的优点是通常更容易在更多操作系统上安装/更新。Adam Katz建议在PCRE中使用\e(相同\x1b)。

根据要过滤的命令选择正则表达式:

perl -pe 's/\e\[[0-9;]*m//g'          # Remove colors only
perl -pe 's/\e\[[0-9;]*[mG]//g'
perl -pe 's/\e\[[0-9;]*[mGKH]//g'
perl -pe 's/\e\[[0-9;]*[a-zA-Z]//g'
perl -pe 's/\e\[[0-9;]*m(?:\e\[K)?//g' # Adam Katz's trick

OP命令行示例:

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' \
      | perl -pe 's/\e\[[0-9;]*m//g'

用法

正如Stuart Cardall的评论所指出的那样,sed项目Ultimate Nginx Bad Bot(1000个星标)使用此命令行来清理电子邮件报告;-)


2
感谢您的sed命令和解释。:)
Redsandro

2
一些颜色代码(例如Linux终端)包含前缀,例如1;31m,最好将其添加;到您的正则表达式中:cat colored.log | sed -r 's/\x1b\[[0-9;]*m//g'否则它们不会被剥离。
Redsandro 2014年


2
请记住,sed带有所示示例的OSX版本不起作用,gsed但是该版本可以。
slm

2
slm关于OSX sed的评论的更多上下文:它不支持\ x1b之类的控制字符。例如,stackoverflow.com/a/ 14881851/ 93345。您可以通过获得gsed命令brew install gnu-sed
steamer25


10

显示^[不是 ^[;它是ESCEsc或产生的ASCII 字符Ctrl[^符号表示Ctrl键)。

ESC是0x1B十六进制或033八进制,因此您必须使用\x1B\033在正则表达式中:

perl -pe 's/\033\[37m//g; s/\033[0m//g'

perl -pe 's/\033\[\d*(;\d*)*m//g'

6

如果您喜欢简单的东西,可以使用strip-ansi模块(需要Node.js):

$ npm install --global strip-ansi-cli

然后像这样使用它:

$ strip-ansi < colors.o

或者只是传递一个字符串:

$ strip-ansi '^[[37mABC^[[0m'

catUUOC)的这种无用用法-应该strip-ansi colors.o或者至少应该这样做strip-ansi < colors.o
斯科特

1
@Scott当然,您也可以这样做strip-ansi < colors.o,但是根据经验,人们对管道更加熟悉。我已经更新了答案。
Sindre Sorhus'2

好的简单解决方案
Penghe Geng


2

“已回答”的问题对我不起作用,因此我创建了此正则表达式来删除由perl Term :: ANSIColor模块产生的转义序列。

cat colors.o | perl -pe 's/\x1b\[[^m]+m//g;

Grawity的正则表达式应该可以正常工作,但是使用+似乎也可以。


4
(1)你是什么意思The "answered" question?你是说接受的答案吗?(2)此命令不起作用-甚至不执行-因为它的引号不匹配(不平衡)。(3)这catUUOC)的无用用法-应该可以做到。(4)谁曾说过文件中的代码?perl -pe command colors.o.o
斯科特

2

我相信这是对所有ANSI转义序列的权威删除:

perl -pe '
  s/\e\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]//g;
  s/\e[PX^_].*?\e\\//g;
  s/\e\][^\a]*(?:\a|\e\\)//g;
  s/\e[\[\]A-Z\\^_@]//g;'

(请注意,perl的,像许多其他语言(但不是SED),接受\e作为转义字符Esc\x1b\033通过代码,如终端显示^[。我在这里使用它,因为它看起来更直观。)

该perl命令可以在一行中全部运行,如果有需要,可以替换四个命令:

首先是CSI序列(以的“ Control Sequence Introducer”开头的转义码序列Esc[,它比构成颜色代码和其他文本修饰的Select Graphic Rendition序列涵盖的范围要大得多)。

第二个替换操作删除了其余包含尾随字符并以ST(String Terminator,Esc\)结尾的序列。第三个替换是相同的事情,但也允许操作系统命令序列以BEL\x07\007,经常” \a)结尾。

第四个替换项删除了其余的逃生通道。

还可以考虑删除其他零宽度ASCII字符(例如BEL)和其他更晦涩的C0和C1控制字符。我一直在使用s/[\x00-\x1f\x7f-\x9f\xad]+//g,其中还包括DeleteSoft Hyphen。这不包括统一的高编码零宽度的字符,但我相信这是对无遗ASCII(Unicode的\x00- \xff)。如果执行此操作,请最后删除这些,因为它们可能会涉及较长的序列。


1

“ tput sgr0”离开了此控制字符^(B ^ [
这是对此的修改版本。

perl -pe 's/\e[\[\(][0-9;]*[mGKFB]//g' logfile.log

谢谢...这使我摆脱tput sgr0了其他解决方案似乎无法摆脱的困扰。
TxAG98


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.