我想更容易区分相邻的匹配,同时仍然保留输入的上下文。为了做到这一点,最好循环一下grep发现的每个匹配的颜色列表。
我想修改命令
echo -e "AA\nAABBAABBCC\nBBAABB" | grep --color=always "AABB\|"
所以不要打印:
它会打印出来:
这可以用grep完成吗?我能找到的最接近的答案是matching two different (and non-overlapping) grep queries in different colors。
或者,我怎样才能最容易地在Ubuntu终端中获得此功能?
答案 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
(显然)。
答案 1 :(得分:1)
这可以通过使用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解决方案。
#!/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'
答案 2 :(得分:1)
您可以使用colout
:http://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
在每次匹配时使用逗号分隔的颜色作为颜色映射循环。