Grep - 为每场比赛循环颜色

时间:2014-03-04 09:14:33

标签: bash colors grep

我想更容易区分相邻的匹配,同时仍然保留输入的上下文。为了做到这一点,最好循环一下grep发现的每个匹配的颜色列表。

我想修改命令

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

所以不要打印:

Red only

它会打印出来:

Red and blue

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

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

3 个答案:

答案 0 :(得分:2)

您可以使用grep实现带颜色旋转的perl,并使用实验性正则表达式功能进行单次替换,以便在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(显然)。

enter image description here

答案 1 :(得分:1)

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

在看到阿德里安的回答后,我决定拿出自己的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'

enter image description here

答案 2 :(得分:1)

您可以使用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在每次匹配时使用逗号分隔的颜色作为颜色映射循环。