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:
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:
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