根据一些规则突出显示制表符分隔值

时间:2016-02-27 21:46:32

标签: shell terminal colorize text-coloring ansi-colors

我有一些制表符分隔文件,我想有条件地突出显示某些列或某些值。

源文件示例:

wn       name          Building Name       8       Desc       char       -> bl
wo       bl_id!*       Building Code       8                  char

我想:

  • 当名称后缀为"时,将第2列的内容变为黄色!"
  • 第3列的内容为青色,第7列的内容为绿色,第7列的内容为
  • 把小" *"在第二栏中签到红色

以及其他一些此类规则。

目前我这样做:

cat file.tsv
    | sed -r 's/^([^\t]*)\t([^\t]*)!/\1\t\x1b[33m\2!\x1b[0m/' \
    | sed -r 's/^^([^\t]*)\t([^\t]*)\t(.*)\t-> ([^\t]+)/\1\t\x1b[36m\2\x1b[0m\t\3\t-> \x1b[32m\4\x1b[0m/' \
    | sed -r 's/\*/\x1b[31;1m&\x1b[0m/'

但阅读和更新非常复杂。

有更好的方法吗?我很确定,但是哪一个?

像GRC或Supercat这样的方式还有吗?虽然,我不得不承认我有一个非常重要的约束:我希望解决方案能够在Cygwin中开箱即用。我不想在那里编译自己的工具 - 出于我的代码的可移植性原因。

您是否可以提供有关如何改进代码的提示,以获得这样的"突出显示"功能?

2 个答案:

答案 0 :(得分:1)

您可以使用shell变量(以及tput跨终端类型的可移植性)使脚本更具可读性:

BOLD_RED=$(tput setaf 1; tput bold)
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 3)
CYAN=$(tput setaf 6)
COLOR_OFF=$(tput sgr0)

cat file.tsv
    | sed -r 's/^([^\t]*)\t([^\t]*)!/\1\t'"$YELLOW"'\2!'"$COLOR_OFF"'/' \
    | sed -r 's/^([^\t]*)\t([^\t]*)\t(.*)\t-> ([^\t]+)/\1\t'"$CYAN"'\2'"$COLOR_OFF"'\t\3\t-> '"$GREEN"'\4'"$COLOR_OFF"'/' \
    | sed -r 's/\*/'"$BOLD_RED"'&'"$COLOR_OFF"'/'

同样,您可以为正则表达式块创建一个变量,这是除标签之外的所有内容,例如

NO_TABS='([^\t]*)'

顺便说一句,其中一个sed表达式重复^(错字)。

答案 1 :(得分:1)

你可以用GNU awk这样做(col.awk):

function colText ( text, col) { 
    return sprintf("\033[%sm%s\033[39;0m", col, text); 
}

function yellow( text ){ return colText( text, "33;1" ); }
function cyan  ( text ){ return colText( text, "36;1" ); }
function green ( text ){ return colText( text, "32;1" ); }
function red   ( text ){ return colText( text, "31;1" ); } 

BEGIN {FS=OFS="\t";}

# red * in $2
$2 ~ /\*/ {gsub(/\*/, red("*"), $2); }

# cyan if col 7 present
NF == 7 {print $1, cyan($2), $3, $4, $5, $6, green( $7 ) ;
         next;}

# yellow col2 if there is a !  
$2 ~ /!/ {print $1, yellow($2), $3, $4, $5, $6, $7 }

gawk -f col.awk file.tsv

一样使用它