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

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

检查输出

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'

答案1

角色^[[37m^[[0mANSI 转义序列(CSI 代码)。 也可以看看这些规范

使用 GNUsed

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

使用 macOS 默认设置sed

麦克风建议:

sed -e $'s/\x1b\[[0-9;]*m//g'

macOS 默认sed不支持特殊字符,\e空间光度测量蒸锅25在评论中。

安装gsed

brew install gnu-sed

OP 命令行示例

(OP 即 Original Poster)

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

改进

-e对于 GNU 来说该标志是可选的sed,但对于 macOS 默认来说该标志是必需的sed

sed 's/\x1b\[[0-9;]*m//g'           # Remove color sequences only

汤姆·黑尔建议还删除所有其他转义序列,而不仅仅是使用特定于图形模式转义序列(颜色)的[a-zA-Z]字母:m

sed 's/\x1b\[[0-9;]*[a-zA-Z]//g'    # Remove all escape sequences

[a-zA-Z]可能太宽并且可能会删除太多。米哈乌·法伦斯基米格尔·莫塔建议分别使用[mGKH]和删除一些转义序列[mGKF]

sed 's/\x1b\[[0-9;]*[mGKH]//g'      # Remove color and move sequences
sed 's/\x1b\[[0-9;]*[mGKF]//g'      # Remove color and move sequences
sed 's/\x1b\[[0-9;]*[mGKHF]//g'     # Remove all
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

布里顿·凯林表示K(除了m)从错误/警告中删除颜色gcc。不要忘记重定向gcc 2>&1 | sed...

使用perl

sed在某些操作系统上安装的版本可能受到限制(例如 macOS)。该命令perl的优点是通常更容易在更多操作系统上安装/更新。亚当·卡茨建议在中使用\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'

用法

正如斯图亚特·卡达尔的评论,此sed命令行由项目使用终极 Nginx 恶意机器人(1000 颗星)清理电子邮件报告 ;-)

答案2

如果您使用的是 MacOS,我发现了一个更好的转义序列删除器。检查一下:

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

答案3

ansi2txt

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

cat typescript | ansi2txt | col -b
  • ansi2txt:删除 ANSI 颜色代码
  • col -b:删除^H^M


更新:关于 col 句柄制表符和空格//由@DanielF 提及

〇.关于col句柄空格和制表符

col -bx将 '\t' 替换为 ' ', col -bh将 ' ' 替换为 '\t'。

// 似乎col无法保留空格/制表符,很遗憾。


0. 原始字符串

$ echo -e '        ff\tww' | hd
00000000  20 20 20 20 20 20 20 20  66 66 09 77 77 0a        |        ff.ww.|

1. -h 将空格替换为制表符

$ echo -e '        ff\tww' | col -b | hd
00000000  09 66 66 09 77 77 0a                              |.ff.ww.|
$ echo -e '        ff\tww' | col -bh | hd
00000000  09 66 66 09 77 77 0a                              |.ff.ww.|
$ echo -e '        ff\tww' | col -bxh | hd
00000000  09 66 66 09 77 77 0a                              |.ff.ww.|

2. -x 将制表符替换为空格

$ echo -e '        ff\tww' | col -bx | hd
00000000  20 20 20 20 20 20 20 20  66 66 20 20 20 20 20 20  |        ff      |
00000010  77 77 0a                                          |ww.|
$ echo -e '        ff\tww' | col -bhx | hd
00000000  20 20 20 20 20 20 20 20  66 66 20 20 20 20 20 20  |        ff      |
00000010  77 77 0a                                          |ww.|

3.似乎col无法保留空格和制表符。

答案4

显示的^[内容不是 ^[;它是 ASCII字符,由或(该符号表示 Ctrl 键)ESC产生。EscCtrl[^

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

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

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

相关内容