漂亮的打印列中的颜色转义码 [英] Color escape codes in pretty printed columns

查看:128
本文介绍了漂亮的打印列中的颜色转义码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个制表符分隔的文本文件,该文件发送到column来漂亮地打印"一张表.

I have a tab-delimited text file which I send to column to "pretty print" a table.

原始文件:

1<TAB>blablablabla<TAB>aaaa bbb ccc
2<TAB>blabla<TAB>xxxxxx
34<TAB>okokokok<TAB>zzz yyy

使用column -s$'\t' -t <original file>,我得到

1  blablablabla aaaa bbb xxx
2  blabla       xxxxxx
34 okokokok     zzz yyy

根据需要.现在,我想为列添加颜色.我试图在原始文件中每个制表符分隔的字段周围添加转义代码. column成功以彩色打印,但各列不再对齐.相反,它只是逐字打印TAB分隔符.

as desired. Now I want to add colors to the columns. I tried to add the escape codes around each tab-delimited field in the original file. column successfully prints in color, but the columns are no longer aligned. Instead, it just prints the TAB separators verbatim.

问题是:如何使列对齐,但颜色也要唯一?

The question is: how can I get the columns aligned, but also with unique colors?

我想到了两种方法来实现这一目标:

I've thought of two ways to achieve this:

  1. 调整column参数以使对齐方式与颜色代码一起使用
  2. 将列的输出重定向到另一个文件,并对前两个用空格分隔的字段进行搜索+替换(保证前两列包含空格;最有可能的第三列将包含空格,但不包含TAB字符)
  1. Adjust the column parameters to make the alignment work with color codes
  2. Redirect the output of column to another file, and do a search+replace on the first two whitespace-delimited fields (the first two columns are guaranteed to not contain spaces; the third column most likely will contain spaces, but no TAB characters)

问题是,我不确定该怎么做...

Problem is, I'm not sure how to do either of those two...

作为参考,这是我要传递给column的内容:

For reference, here is what I'm passing to column:

请注意,这些字段确实由TAB字符分隔.我已经通过od确认了这一点.

Note that the fields are indeed separated by TAB characters. I've confirmed this with od.

着色似乎没有问题.我已经有了上面显示的文件,并且颜色代码正常工作.问题是column在我发送带有转义码的输入后将无法对齐.我正在考虑将没有 颜色代码的字段传递给column,然后在每个字段之间复制确切数量的空格column输出,并在漂亮的打印方案中使用它.

There doesn't seem to be an issue with the colorization. I already have the file shown above with the color codes working. The issue is column won't align once I send it input with escape codes. I am thinking of passing the fields without color codes to column, then copying the exact number of spaces column output between each field, and using that in a pretty print scheme.

推荐答案

我写了一个bash版本的列(类似于util-linux中的列),它使用了颜色代码:

I wrote a bash version of column (similar to the one from util-linux) which works with color codes:

#!/bin/bash
which sed >> /dev/null || exit 1

version=1.0b
editor="Norman Geist"
last="04 Jul 2016"

# NOTE: Brilliant pipeable tool to format input text into a table by 
# NOTE: an configurable seperation string, similar to column
# NOTE: from util-linux, but we are smart enough to ignore 
# NOTE: ANSI escape codes in our column width computation
# NOTE: means we handle colors properly ;-)

# BUG : none

addspace=1
seperator=$(echo -e " ")
columnW=()
columnT=()

while getopts "s:hp:v" opt; do
  case $opt in
s ) seperator=$OPTARG;;
p ) addspace=$OPTARG;;
v ) echo "Version $version last edited by $editor ($last)"; exit 0;;
h ) echo "column2 [-s seperator] [-p padding] [-v]"; exit 0;;
* ) echo "Unknow comandline switch \"$opt\""; exit 1
  esac
done
shift $(($OPTIND-1))

if [ ${#seperator} -lt 1 ]; then
  echo "Error) Please enter valid seperation string!"
  exit 1
fi

if [ ${#addspace} -lt 1 ]; then
  echo "Error) Please enter number of addional padding spaces!"
  exit 1
fi

#args: string
function trimANSI()
{
  TRIM=$1
  TRIM=$(sed 's/\x1b\[[0-9;]*m//g' <<< $TRIM); #trim color codes
  TRIM=$(sed 's/\x1b(B//g'         <<< $TRIM); #trim sgr0 directive
  echo $TRIM
}

#args: len
function pad()
{
  for ((i=0; i<$1; i++))
  do 
echo -n " "
  done
}

#read and measure cols
while read ROW
do
  while IFS=$seperator read -ra COLS; do
ITEMC=0
for ITEM in "${COLS[@]}"; do
  SITEM=$(trimANSI "$ITEM"); #quotes matter O_o
  [ ${#columnW[$ITEMC]} -gt 0 ] || columnW[$ITEMC]=0
  [ ${columnW[$ITEMC]} -lt ${#SITEM} ] && columnW[$ITEMC]=${#SITEM}
  ((ITEMC++))
done
columnT[${#columnT[@]}]="$ROW"
  done <<< "$ROW"
done

#print formatted output
for ROW in "${columnT[@]}"
do
  while IFS=$seperator read -ra COLS; do
ITEMC=0
for ITEM in "${COLS[@]}"; do
  WIDTH=$(( ${columnW[$ITEMC]} + $addspace ))
  SITEM=$(trimANSI "$ITEM"); #quotes matter O_o
  PAD=$(($WIDTH-${#SITEM}))

  if [ $ITEMC -ne 0 ]; then
    pad $PAD
  fi

  echo -n "$ITEM"

  if [ $ITEMC -eq 0 ]; then
    pad $PAD
  fi

  ((ITEMC++))
done
  done <<< "$ROW"
  echo ""
done

示例用法:

bold=$(tput bold)
normal=$(tput sgr0)
green=$(tput setaf 2)

column2 -s § << END
${bold}First Name§Last Name§City${normal}
${green}John§Wick${normal}§New York
${green}Max§Pattern${normal}§Denver
END

输出示例:

这篇关于漂亮的打印列中的颜色转义码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆