使用 bash 从文本文件中删除 ANSI 颜色代码

问题描述 投票:0回答:5

我有一个 bash 脚本,可以运行并输出到文本文件,但是它使用的颜色代码也包含在内,我想知道如何从文件中删除它们,即

^[[38;1;32mHello^[[39m
^[[38;1;31mUser^[[39m

所以我只想留下Hello和User

bash shell
5个回答
23
投票
sed -r "s/\x1B\[(([0-9]{1,2})?(;)?([0-9]{1,2})?)?[m,K,H,f,J]//g" file_name

此命令从文件中删除特殊字符和颜色代码

这些是一些 ANSI 代码:

ESC[#;#H or ESC[#;#f
将光标移至第 # 行、第 # 列
ESC[2J
清晰的屏幕和主页光标
ESC[K
清除到行尾,

请注意,如果代码清晰,则既没有数字也没有分号

;

同意以下评论: 如果数字超过 2 位,请使用此:

sed -r "s/\x1B\[(([0-9]+)(;[0-9]+)*)?[m,K,H,f,J]//g" filename

11
投票

我的解决方案:

... | sed $'s/\e\\[[0-9;:]*[a-zA-Z]//g'

冒号用于支持某些旧终端类型的转义。


1
投票

这能解决问题吗?

$ echo "^[[38;1;32mHello^[[39m" | sed -e 's/\^\[\[[0-9;]\{2,\}m//g'
Hello

干杯!!


0
投票

解决方案

大多数投票的答案对我来说并不直接有效。它需要一个小小的调整。

如何

  • 在 bash shell 中运行以下命令,或将以下代码块添加到现有别名列表中,以便将来能够重用
    decolor
    别名。
## Decolor ANSI Colored Output
# example: (see preview in VSCode editor)
# >>> cat <filepath> | decolor | code -
alias decolor.styles='sed -E "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})*)?[m,K,H,f,J]//gm"'
alias decolor.reset='sed -E "s/\x1B\([A-Z]{1}(\x1B\[[m,K,H,f,J])?//gm"'
alias decolor='decolor.styles | decolor.reset'

用法

cat coloredtext.txt | decolor

输出

PRESENT: /somepath/somefile_a.csv
PRESENT: /somepath/somefile_b.csv

虚拟数据

# File Name: coloredtext.txt
# [1m[32mPRESENT:(B[m [32m/somepath/somefile_a.csv(B[m
# [1m[32mPRESENT:(B[m [32m/somepath/somefile_b.csv(B[m
\x1B[1m\x1B[32mPRESENT:\x1B(B\x1B[m \x1B[32m/somepath/somefile_a.csv\x1B(B\x1B[m
\x1B[1m\x1B[32mPRESENT:\x1B(B\x1B[m \x1B[32m/somepath/somefile_b.csv\x1B(B\x1B[m

0
投票

TL;博士

这是删除任何有效 CSI(控制序列引入器)序列的正确命令:

LC_ALL=C.UTF8 sed -r "s/\x1B\[[\x30-\x3F]*[\x20-\x20F]*[\x40-\x7E]//g"

说明

sed 正则表达式

\x1B\[[\x30-\x3F]*[\x20-\x20F]*[\x40-\x7E]
与 CSI 序列的 Wikipedia 描述相匹配:

  • \x1B\[
    :以
    ESC [
  • 开头
  • [\x30-\x3F]*
    :0x30–0x3F 范围内的任意数量(包括无)“参数字节”(ASCII
    0–9:;<=>?
  • [\x20-\x20F]*
    :0x20–0x2F 范围内任意数量的“中间字节”(ASCII 空格和
    !"#$%&'()*+,-./
  • [\x40-\x7E]
    :以 0x40–0x7E 范围内的单个“最终字节”结束(ASCII
    @A–Z[\]^_
    a–z{|}~`)

字符排序取决于区域设置。例如,如果您使用

en_US.UTF8
,您将收到以下错误:

sed: -e expression #1, char 47: Invalid range end

为了避免这种情况,请在命令开头添加

LC_ALL=C.UTF8
(这只会更改
LC_ALL
命令的
sed
值,以下命令不受影响)

© www.soinside.com 2019 - 2024. All rights reserved.