根据几条规则突出显示制表符分隔值

Highlight tab-separated values based on a couple of rules

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

源文件示例:

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

我想:

以及其他一些此类规则。

目前我是这样做的:

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

但是阅读和更新起来相当复杂。

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

GRC 或 Supercat 之类的东西是否可行?不过,我不得不承认我有一个非常重要的约束:我希望解决方案在 Cygwin 中开箱即用。不想在那里编译自己的工具——出于我代码的可移植性原因。

您能否提供有关如何改进代码以获得这样的 "highlight" 功能的提示?

您可以通过使用 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]*)!/\t'"$YELLOW"'!'"$COLOR_OFF"'/' \
    | sed -r 's/^([^\t]*)\t([^\t]*)\t(.*)\t-> ([^\t]+)/\t'"$CYAN"''"$COLOR_OFF"'\t\t-> '"$GREEN"''"$COLOR_OFF"'/' \
    | sed -r 's/\*/'"$BOLD_RED"'&'"$COLOR_OFF"'/'

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

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

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

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

function colText ( text, col) { 
    return sprintf("3[%sm%s3[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 
 ~ /\*/ {gsub(/\*/, red("*"), ); }

# cyan if col 7 present
NF == 7 {print , cyan(), , , , , green(  ) ;
         next;}

# yellow col2 if there is a !  
 ~ /!/ {print , yellow(), , , , ,  }

这样使用gawk -f col.awk file.tsv