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

use*_*001 116 regex perl awk sed

检查输出

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";'
Run Code Online (Sandbox Code Playgroud)

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

^[[37mABC
^[[0m
Run Code Online (Sandbox Code Playgroud)

如何从输出文件中删除 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'
Run Code Online (Sandbox Code Playgroud)

oHo*_*oHo 173

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

使用 GNU sed

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

? 在 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'
Run Code Online (Sandbox Code Playgroud)

Tom Hale建议删除所有其他转义序列,[a-zA-Z]而不是仅使用m特定于图形模式(颜色)转义序列的字母。但[a-zA-Z]可能太宽,可能删除太多。米夏?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
Run Code Online (Sandbox Code Playgroud)
sed 's/\x1b\[[0-9;]*m//g'
Run Code Online (Sandbox Code Playgroud)

使用 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
Run Code Online (Sandbox Code Playgroud)

OP 命令行示例:

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

用法

正如Stuart Cardall的评论所指出的,该sed命令行被Ultimate Nginx Bad Bot(1000 星)项目用于清理电子邮件报告;-)

  • 一些颜色代码(例如 Linux 终端)包含一个前缀,例如 `1;31m` 所以最好在你的正则表达式中添加 `;`: `cat coloured.log | sed -r 's/\x1b\[[0-9;]*m//g'` 否则它们不会被剥离。 (3认同)
  • 在 mac `sed -e $'s/\x1b\[[0-9;]*m//g'` 上没有 gsed @slm @steamer25 (3认同)
  • 感谢您的 `sed` 命令和解释。:) (2认同)
  • 请记住,`sed` 的 OSX 版本在显示的示例中不起作用,但是 `gsed` 版本可以。 (2认同)
  • slm 关于 OSX sed 的更多评论:它不支持像 \x1b 这样的控制字符。例如,/sf/answers/1041729601/。您可以通过 `brew install gnu-sed` 获取 gsed 命令。 (2认同)

小智 30

我发现了一个更好的转义序列去除器。检查这个:

perl -pe 's/\x1b\[[0-9;]*[mG]//g'

  • @Blaisorblade 它适用于 OS X,而 `sed -r` 不适用。 (8认同)
  • 接受的答案 (http://superuser.com/a/380778/46794) 有何改进? (3认同)

use*_*686 12

显示^[不是 ^[;它是ESCEscor产生的 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'
Run Code Online (Sandbox Code Playgroud)


Sin*_*hus 10

如果你喜欢简单的东西,你可以使用我的strip-ansi-cli包(需要Node.js):

$ npm install --global strip-ansi-cli
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

$ strip-ansi < colors.o
Run Code Online (Sandbox Code Playgroud)

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

$ strip-ansi '^[[37mABC^[[0m'
Run Code Online (Sandbox Code Playgroud)

  • `如果你更喜欢简单的东西......`继续建议安装一个完整的平台,一个带来数十个未经验证的依赖项的工具......如今'简单'真的意味着不同的东西......妈妈 (4认同)
  • 您应该透露您是此软件包的作者,[根据超级用户政策](https://superuser.com/help/promotion)。 (2认同)

Tom*_*ale 8

commandlinefu 给出了这个答案,它去除了 ANSI 颜色以及移动命令:

sed "s,\x1B\[[0-9;]*[a-zA-Z],,g"
Run Code Online (Sandbox Code Playgroud)

对于颜色,您需要:

 sed "s,\x1B\[[0-9;]*m,,g"
Run Code Online (Sandbox Code Playgroud)


yur*_*hen 8

ansi2txt

https://unix.stackexchange.com/a/527259/116915

cat typescript | ansi2txt | col -b
Run Code Online (Sandbox Code Playgroud)
  • ansi2txt: 删除 ANSI 颜色代码
  • col -b: 删除^H^M

  • `sudo apt install colorized-logs` (5认同)

Ada*_*atz 7

我相信这是对所有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;'
Run Code Online (Sandbox Code Playgroud)

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

这个 perl 命令,如果你愿意,你可以在一行上运行,它有四个替换:

第一个是 CSI 序列(以 的“控制序列介绍器”开头的转义码序列Esc[,它涵盖的内容比构成颜色代码和其他文本装饰的Select Graphic Rendition 序列要多得多)。

第二次替换删除涉及尾随字符并以 ST(字符串终止符, )终止的剩余序列Esc\。第三个替换是相同的,但也允许操作系统命令序列以BEL结尾(\x07\007、 经常\a)。

第四次替换删除剩余的转义符。

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


小智 6

还有一个专用工具可以完成这项工作:ansifilter。使用默认的--text输出格式。

参考: https: //stackoverflow.com/a/6534712