按颜色过滤命令的输出

km6*_*zla 15 grep colors filter text

我正在运行一个不提供过滤其输出的方法的实用程序。输出文本中没有任何内容表明特定功能失败,但它确实显示为红色。输出太长,以至于最后当它报告一些错误时,我不能总是滚动查看发生错误的输出。

如何过滤掉非红色文本?

伪代码:

dolongtask | grep -color red

编辑

该命令也输出其他颜色,我需要能够过滤所有不是红色的文本。文本着色也是多行的。

Gil*_*il' 15

颜色的切换是通过嵌入在文本中的转义序列完成的。程序总是会发出ANSI 转义序列,因为现在几乎所有终端都支持这样。

将前景色切换为红色的转义序列是\e[31m,其中\e指定转义字符(八进制 033、十六进制 1b,也称为 ESC^[和各种其他名称)。30-39 范围内的数字设置前景色;其他数字设置不同的属性。\e[0m将所有属性重置为其默认值。运行cat -v以检查程序打印的内容,它可能会使用一些变体,例如\e[0;31m首先重置所有属性,或者\e[3;31还打开斜体(许多终端不支持)。

在 ksh、bash 或 zsh 中,您可以使用$'…'在引号内启用反斜杠转义,这样您就可以键入$'\e'以获取转义字符。请注意,您必须将要传递给的任何反斜杠加倍grep。在 中/bin/sh,您可以使用"$(printf \\e)"或键入文字转义字符。

使用 GNUgrep -o选项,以下代码段过滤红色文本,假设它以转义序列 开头\e[31m,以\e[0m\e[30m在同一行结束,并且不包含嵌入的转义序列。

grep -Eo $'\e\\[31m[^\e]*\e\\[[03]?m'
Run Code Online (Sandbox Code Playgroud)

以下awk代码段提取红色文本,即使它是多行的。

awk -v RS='\033' '
    match($0, /^\[[0-9;]*m/) {
        color = ";" substr($0, 2, RLENGTH-2) ";";
        $0 = substr($0, RLENGTH+1);
        gsub(/(^|;)0*[^03;][0-9]*($|;)/, ";", color);
        red = (color ~ /1;*$/)
    }
    red'
Run Code Online (Sandbox Code Playgroud)

这是一个保留颜色更改命令的变体,如果您要过滤多种颜色(此处为红色和洋红色),这可能会很有用。

awk -v RS='\033' '
    match($0, /^\[[0-9;]*m/) {
        color = ";" substr($0, 2, RLENGTH-2) ";";
        printf "\033%s", substr($0, 1, RLENGTH);
        $0 = substr($0, RLENGTH+1);
        gsub(/(^|;)0*[^03;][0-9]*($|;)/, ";", color);
        desired = (color ~ /[15];*$/)
    }
    desired'
Run Code Online (Sandbox Code Playgroud)


sav*_*nto 6

您可以使用 grep 查找控制字符,其中一些字符负责在终端上制作漂亮的颜色。

dolongtask | grep '[[:cntrl:]]'
Run Code Online (Sandbox Code Playgroud)

例如,这将一个红色的“测试”回显到 grep 中,由于它被控制字符包围,它找到了它:

$ echo -e '\033[00;31mtest\033[00m' | grep --color=none '[[:cntrl:]]'
test     <-- in red
Run Code Online (Sandbox Code Playgroud)

--color=none只是为了确保 grep 不会将自己的着色应用于匹配的输出,而是忠实地打印整行,以便 shell 解释控制字符。