Color escape codes in pretty printed columns Color escape codes in pretty printed columns unix unix

Color escape codes in pretty printed columns


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

#!/bin/bashwhich sed >> /dev/null || exit 1version=1.0beditor="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 : noneaddspace=1seperator=$(echo -e " ")columnW=()columnT=()while getopts "s:hp:v" opt; do  case $opt ins ) 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  esacdoneshift $(($OPTIND-1))if [ ${#seperator} -lt 1 ]; then  echo "Error) Please enter valid seperation string!"  exit 1fiif [ ${#addspace} -lt 1 ]; then  echo "Error) Please enter number of addional padding spaces!"  exit 1fi#args: stringfunction 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: lenfunction pad(){  for ((i=0; i<$1; i++))  do echo -n " "  done}#read and measure colswhile read ROWdo  while IFS=$seperator read -ra COLS; doITEMC=0for 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++))donecolumnT[${#columnT[@]}]="$ROW"  done <<< "$ROW"done#print formatted outputfor ROW in "${columnT[@]}"do  while IFS=$seperator read -ra COLS; doITEMC=0for 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

Example usage:

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}§DenverEND

Output example:

enter image description here


I would use awk for the colorization (sed can be used as well):

awk '{printf "\033[1;32m%s\t\033[00m\033[1;33m%s\t\033[00m\033[1;34m%s\033[00m\n", $1, $2, $3;}' a.txt 

and pipe it to column for the alignment:

... | column -s$'\t' -t

Output:

output


A solution using printf to format the ouput as well :

while IFS=$'\t' read -r c1 c2 c3; do    tput setaf 1; printf '%-10s' "$c1"    tput setaf 2; printf '%-30s' "$c2"    tput setaf 3; printf '%-30s' "$c3"    tput sgr0; echodone < file

enter image description here