【问题标题】:Grep - Cycle through colors for each matchGrep - 循环显示每场比赛的颜色
【发布时间】:2014-04-05 17:20:28
【问题描述】:

我想更轻松地区分相邻的匹配项,同时仍保留输入的上下文。为此,最好循环浏览 grep 找到的每个匹配项的颜色列表。

我想修改命令

echo -e "AA\nAABBAABBCC\nBBAABB" | grep --color=always "AABB\|"

这样就不用打印了:

它会打印:

这可以在 grep 中完成吗?我能找到的最接近的答案是matching two different (and non-overlapping) grep queries in different colors

或者,我怎样才能最轻松地在 Ubuntu 终端中获得此功能?

【问题讨论】:

  • Can this be done in grep? -- 没有。

标签: bash colors grep


【解决方案1】:

您可以使用perl 实现带有颜色旋转的grep,并使用实验性正则表达式功能将每个匹配项包装在ANSI 转义序列中进行单次替换。这里有一些东西可以作为你可以包装在 shell 函数中的起点:

$ printf "FOOBARFOOFOOFOOBAR\nFOOBARFOOFOOFOOBARFOOFOOFOOFOOFOOFOOFOOFOOFOOFOOFOOFOO\n" \
    | perl -ne 'next unless /FOO/; $m=0; s#(?<!\[0mFOO)\K((?{$n=30+(++$m%8)})FOO)#\033\[1;${n}m\1\033\[0m#g; print'

不是很漂亮,但至少很简短。

我懒得重做屏幕截图,但您可能想通过 $n = 31 + (++$m % 7) 跳过深灰色。如果您只想要两种颜色,请将除数设置为 2(显然)。

【讨论】:

    【解决方案2】:

    Awk

    这可以通过使用 ANSI escape sequences 的 awk 脚本来实现

    #!/usr/bin/awk -f
    # USAGE: echo -e "AA\nAABBAABBCC\nBBAABB" | awk -f color_grep.awk -v regex="AABB"
    
    BEGIN {
      # Bold Red ANSI Code
      c[0] = "\x1b[1;31m"
      # Bold Blue ANSI Code
      c[1] = "\x1b[1;34m"
      # Default ANSI Code
      n = "\x1b[0m"
    }
    
    {
      i--
      j = 1
    
      do {
        temp = $0;
        i = (i + 1) % 2
        $0 = gensub("(" regex ")", c[i] "\\1" n, j, temp);
        j++
      } while ($0 != temp)
    
      print $0
    }
    

    或作为命令行上的单行符:

    echo -e "AA\nAABBAABBCC\nBBAABB" | awk 'BEGIN { c[0]="\x1b[1;31m"; c[1]="\x1b[1;34m"; n="\x1b[0m"} { i--; j=1; do { $0=gensub(/(AABB)/, c[i=(i+1)%2] "\\1" n, j++, temp=$0); } while ($0!=temp) print $0 }'


    Perl

    看到 Adrian 的回答后,我决定想出自己的 perl 解决方案。

    #!/usr/bin/perl
    # USAGE: echo -e "AA\nAABBAABBCC\nBBAABB" | ~/color_grep.perl "AABB"
    
    $regex = @ARGV[0];
    
    # Generates ANSI escape sequences for bold text colored as follows:
    # 0 - Red, 2 - Green, 3- Yellow, 4 - Blue, 5 - Magenta, 6 - Cyan
    sub color { "\033\[1;" . (31 + $_[0] % 6) . "m" }
    
    # ANSI escape sequence for default text
    $default = "\033\[0m";
    
    while (<STDIN>) {
      # Surround the matched expression with the color start and color end tags.
      # After outputting each match, increment to the next color index
      s/($regex)/color($i++) . $1 . $default/ge;
      print;
    }
    

    作为一个班轮:

    printf "FOOBARFOOFOOFOOBAR\nFOOBARFOOFOOFOOBARFOOFOOFOOFOOFOOFOOFOOFOOFOOFOOFOOFOO\n" | perl -ne 'BEGIN{sub c {"\033\[1;".(31+$_[0]%6)."m"} $d="\033\[0m";} s/(FOO)/c($i++).$1.$d/ge; print'

    【讨论】:

      【解决方案3】:

      你可以使用colouthttp://nojhan.github.io/colout/

      此示例将通过彩虹色循环为文本流中的图案着色。

      echo -e "AA\nAABBAABBCC\nBBAABB" | colout AABB rainbow
      

      您可以将rainbow 更改为random,使用其他颜色映射或动态定义:

      echo -e "AA\nAABBAABBCC\nBBAABB" | colout -c AABB red,blue
      

      -c 选项指示colout 在每次匹配时循环使用逗号分隔的颜色,并将它们用作颜色图。

      【讨论】:

        猜你喜欢
        • 2021-03-06
        • 2022-11-23
        • 2021-11-24
        • 2013-11-01
        • 2014-01-01
        • 2021-08-24
        • 1970-01-01
        • 2016-10-16
        • 2021-12-13
        相关资源
        最近更新 更多