Colored escape codes in fairly printed columns

I have a tab delimited text file that I send to column for a "beautiful print" table.

Original file:

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

Using column -s$'\t' -t <original file> , I get

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

optional. Now I want to add colors to the columns. I tried adding escape codes around each tab delimited field in the source file. column prints successfully in color, but the columns are no longer aligned. Instead, it simply prints the TAB delimiters verbatim.

Question: how can I get column alignment, but also with unique colors?

I thought of two ways to achieve this:

  • Adjust column parameters to align with color codes.
  • Redirect the output of the column to another file and perform a search + replace in the first two fields with a space (the first two columns are guaranteed not to contain spaces, and the third column will most likely contain spaces, but not TAB characters)

The problem is that I'm not sure how to do either of these two ...

For reference, here is what I go to column :

Original file with color codes

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

edit:

It seems like no problem with the coloring. I already have the file shown above with working color codes. Problem: column will not be aligned as soon as I send it using escape codes. I am thinking of passing colors without color codes for column , and then copying the exact number of column spaces displayed between each field and using this in a beautiful print scheme. A.

+8
unix bash escaping multiple-columns
source share
3 answers

I wrote a version of a bash column (similar to the one from util-linux) that 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 

Usage example:

 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 

Output Example:

enter image description here

+3
source share

I would use awk for coloring ( sed can also be used):

 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 move it to column to align:

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

Output:

output

+2
source share

Solution using printf to format output:

 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; echo done < file 

enter image description here

+2
source share

All Articles