从输出中删除颜色

Paw*_* P. 118 unix bash console colors ansi-escape

我有一些产生颜色的脚本,我需要摆脱这个.

#!/bin/bash

exec > >(tee log)   # redirect the output to a file but keep it on stdout
exec 2>&1

./somescript
Run Code Online (Sandbox Code Playgroud)

输出是(在日志文件中):

java (pid  12321) is running...@[60G[@[0;32m  OK  @[0;39m]
Run Code Online (Sandbox Code Playgroud)

我不知道怎么把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"
Run Code Online (Sandbox Code Playgroud)

但现在它给了我(在日志文件中):

java (pid  12321) is running...@[60G[  OK  ]
Run Code Online (Sandbox Code Playgroud)

我怎么能删除这个' @[60G

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

Jef*_*ica 138

根据维基百科,您正在使用[m|K]sed命令是专门设计用于处理m(颜色命令)和K("擦除部分行"命令).您的脚本正在尝试将绝对光标位置设置为60(^[[60G)以获得一行中的所有OK,您的sed行不会覆盖.

(正确地,[m|K]应该是(m|K)或者[mK],因为你不是想要匹配管道角色.但是现在这并不重要.)

如果将命令中的最终匹配切换为[mGK](m|G|K),则应该能够捕获该额外的控制序列.

./somescript | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g"
Run Code Online (Sandbox Code Playgroud)

  • BSD/OSX用户:我们通常没有sed的-r选项.`brew install gnu-sed`将安装一个功能强大的版本.用`gsed`运行. (25认同)
  • 更正确的形式是 `sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,3})*)?[mGK]//g"` ,因为可以有更多项,并且它们也可以是 3 位数长。例如 `\e[38;5;123m` 甚至 `\e[38;5;123;48;5;246m`。 (7认同)
  • 将其添加为 `alias decolorize='sed -r "s/\\x1B\\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK] //g"'` 到你的 bashrc 创建了一个非常好的实用程序,可以用作 `command | decolorize` 和“decolorize file.log”。 (4认同)
  • 这不能可靠地工作,因为可以有第三个值(ala` [38; 5; 45m`).这个替代答案适用于https://unix.stackexchange.com/a/55547/168277 (3认同)
  • @edi9999 据我所知,区别在于超过 16 种颜色的颜色设置(如 `setaf` 支持)需要更多参数,而不仅仅是两个;我的正则表达式支持两个。将第一个“?”更改为“*”应该会有所帮助。处理“sgr0”是可能的,但根据搜索,它可能超出了这个基于正则表达式的黑客答案的范围。 (2认同)

Joe*_*ieu 25

我无法从其他任何答案中获得不错的结果,但以下内容对我有用:

somescript | sed -r "s/[[:cntrl:]]\[[0-9]{1,3}m//g"
Run Code Online (Sandbox Code Playgroud)

如果我只删除了控制字符"^ [",则它会留下其余的颜色数据,例如"33m".包括颜色代码和"m"就可以了.我对s /\x1B感到困惑// g无效,因为\ x1B [31m肯定适用于echo.

  • 在OSX(BSD sed)上,使用`-E`而不是`-r`来扩展正则表达式.可以找到更多[这里](https://unix.stackexchange.com/a/131940) (5认同)
  • 因为它们可能是用分号分隔的多个数字(用于背景颜色,粗体,斜体等等).这个命令对我有用:`sed -r"s/[[:cntrl:]]\[([0-9] {1,3};)*[0-9] {1,3} m // g "` (4认同)

gre*_*lon 14

对于Mac OSX或BSD使用

./somescript | sed $'s,\x1b\\[[0-9;]*[a-zA-Z],,g'
Run Code Online (Sandbox Code Playgroud)


Jua*_*uan 12

还有一个处理 ANSI 转义序列的专用工具:ansifilter。使用默认--text输出格式去除所有 ANSI 转义序列(注意:不仅仅是着色)。

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

  • 如果您想自己构建它,源代码位于 https://gitlab.com/saalen/ansifilter/ (2认同)

edi*_*999 11

我也有一个问题,有时,SI字符出现.

例如,这个输入发生了: echo "$(tput setaf 1)foo$(tput sgr0) bar"

这是一种去除SI字符(移入)的方法(0x0f)

./somescript | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | sed "s/\x0f//g"
Run Code Online (Sandbox Code Playgroud)

  • 不知道为什么这个答案得到的信任如此之少。这是唯一对我有用的... (2认同)

meu*_*rus 11

恕我直言,大多数这些答案都很难限制转义码内的内容.结果,它们最终丢失了常见代码,例如[38;5;60m(256色模式的前景ANSI颜色60).

它们还需要-r启用GNU扩展的选项.这些不是必需的; 他们只是让正则表达式更好.

这是一个更简单的答案,处理256色转义并适用于非GNU的系统sed:

./somescript | sed 's/\x1B\[[0-9;]\+[A-Za-z]//g'
Run Code Online (Sandbox Code Playgroud)

这将捕获以任何开头的[,具有任意数量的小数和分号,并以字母结尾的任何内容.这应该捕获任何常见的ANSI转义序列.

对于funsies,这是一个更大,更通用(但未经测试)的解决方案,适用于所有可想到的ANSI转义序列:

./somescript | sed 's/\x1B[@A–Z\\\]^_]|\x1B\[[0–9:;<=>?]*[-!"#$%&\'()*+,.\/]*[@A–Z[\\\]^_`a–z{|}~]//g'
Run Code Online (Sandbox Code Playgroud)

(如果你有@ edi9999的SI问题,添加| sed "s/\x0f//g"到最后;这适用于任何控件字符,通过替换0f不需要的字符的十六进制)

  • 这是我首选的答案,但对于我的用例来说,有一个小问题,我正在处理的输出包含未被捕获的“^[[m”。通过像这样修改`./somescript | 来解决 sed 's/\x1B\[[0-9;]*[A-Za-z]//g'` (2认同)

小智 9

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

./somescript | tr -d '[:cntrl:]'
Run Code Online (Sandbox Code Playgroud)

  • 突然间它也删除了新的线条 (28认同)
  • 它实际上让代码在那里,见ls -l +你的命令:`rwxr-xr-x 1 tokra admin 22 Oct 18 14:21 [0m [01; 36m/usr/local/opt/gradle [0m - > [01; 34米../地窖/ gradle这个/ 4.2.1 [0米/` (5认同)
  • 控制代码不是 ANSI 代码。这根本没有回答问题。 (4认同)
  • 我喜欢这个优雅的答案,即使它不仅仅是去除颜色.谢谢! (3认同)

Die*_*ano 8

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

TERM=dumb ./somescript 
Run Code Online (Sandbox Code Playgroud)

例如,如果您尝试

TERM=dumb tput sgr0 | xxd
Run Code Online (Sandbox Code Playgroud)

你会看到它没有产生任何输出

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

Run Code Online (Sandbox Code Playgroud)

确实如此(对于 xterm-256color)。


小智 7

我有一个类似的问题。我发现的所有解决方案都适用于颜色代码,但没有删除"$(tput sgr0)"(重置属性)添加的字符。

davemyron注释中的解决方案为例,以下示例中结果字符串的长度为9,而不是6:

#!/usr/bin/env bash

string="$(tput setaf 9)foobar$(tput sgr0)"
string_sed="$( sed -r "s/\x1B\[[0-9;]*[JKmsu]//g" <<< "${string}" )"
echo ${#string_sed}
Run Code Online (Sandbox Code Playgroud)

为了正常工作,必须扩展正则表达式以匹配sgr0(“ \E(B”)添加的序列:

string_sed="$( sed -r "s/\x1B(\[[0-9;]*[JKmsu]|\(B)//g" <<< "${string}" )"
Run Code Online (Sandbox Code Playgroud)


Léa*_*ris 7

纯 Bash 中更简单的函数,用于从文本流中过滤掉常见的 ANSI 代码:

# Strips common ANSI codes from a text stream

shopt -s extglob # Enable Bash Extended Globbing expressions
ansi_filter() {
  local line
  local IFS=
  while read -r line || [[ "$line" ]]; do
    echo "${line//$'\e'[\[(]*([0-9;])[@-n]/}"
  done
}
Run Code Online (Sandbox Code Playgroud)

看:

  1. linuxjournal.com:扩展通配符
  2. gnu.org:Bash 参数扩展


use*_*453 7

我在 Debian 的软件包中遇到了ansi2txt工具colorized-logs。该工具从 STDIN 中删除 ANSI 控制代码。

用法示例:

./somescript | ansi2txt
Run Code Online (Sandbox Code Playgroud)

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

  • Ubuntu 的标准存储库中存在软件包“colorized-logs”,这使得通过“sudo apt install colorized-logs”即可轻松安装该工具。它工作得很好,我还没有发现它有什么问题。这应该是官方的答案。 (7认同)
  • 对于 AUR 人员来说也是如此:aur/colorized-logs (2认同)