暗无天日

=============>DarkSun的个人博客

如何去除ANSI Escape Sequences

通过 ANSI Escape Code 可以让终端上的输出更加华丽醒目,但是另一方面又让在脚本中抓取内容变得困难。

本文通过分析ANSI Escape Code的结构来尝试使用sed命令去除ANSI Escape Sequences。

ANSI Escape Code的结构

通常,一个 ANSI Escape Code 是以 ESC(0x1B) 开头的, 其中最常用的Code被称为CSI(Control Sequence Introducer),是以 ESC(0x1B)[(0x5B) 这两个字符开头的,以 m 字符结尾,中间包含着0个到多个的 SGR 参数。 这些 SGR 参数决定了要如何设置显示的属性,每个 SGR 参数以 ; 进行分隔。 而且这些 SGR 参数通常来说是1-2个数字,而且忽略的话,则默认表示 0

完整的ANSI Escape Code的定义特别复杂,有兴趣的同学可以查看它的 WikiPedia 页面

用sed过滤掉ANSI Escape Code

了解了 ANSI Escape Code 的结构后,我们就可以尝试用 sed 对其进行过滤了。其语句为:

sed  "s/\x1b\[([0-9]{1,2})?(;[0-9]{1,2})*m//g"

其中:

  • \x1b\[ 匹配 CSI 的开头部分,这里 \x1b 使用的是十六进制表示法,也可以直接输入  (方法是先按下Ctrl+v 再按 ESC)
  • ([0-9]{1,2}) 匹配 SGR 部分
  • ([0-9]{1,2})? 表示0个或1个 SGR
  • (;[0-9]{1,2})* 表示0个或1个 ;SGR
  • m 匹配 CSI 的结尾部分

如果觉得太复杂,也可以直接简化成

sed 's/\[[^m]*m//g'