In bash scripts I like to use printf "%-20s" "some string"
to create columns that line up. That works great with regular text, but not really for multi-byte unicode, nor if using any kind of terminal decoration.
Works great:
for i in string longer_string Some_kind_of_monstrosity ; do
printf "%-20s" $i ; echo " OK"
done
Everything is reasonably well lined up:
string OK
longer_string OK
Some_kind_of_monstrosity OK
However - it doesn't work very well with multi-byte unicode or colour codes:
printred () { tput setaf 1; printf %b "$*"; tput sgr0; }
printf "%-20s" test ; echo " NOK"
printf "%-20s" $(printred RED) ; echo " NOK"
printf "%-20s" "★★★★" ; echo " NOK"
It looks like both the bash builtin printf
and the coreutils/printf simply count the number of bytes in the string, rather than how many character that will be visible on the output:
test NOK
RED NOK
★★★★ NOK
Is there a way to achieve this nicely in bash? (I'm using bash 5.0.17, but I'm not averse to using some other tool.)
CodePudding user response:
simple command column
meets your need.
column -t < input.txt
CodePudding user response:
The %-20s
is just blindly counting bytes and it does not understand ANSI control sequences so you can ask it to count only the text part.
Example:
RESET=$( tput sgr0 )
RED=$( tput setaf 1 )
printf '%-20s OK?\n' foobar
printf '%s%-20s%s OK?\n' "$RED" foobar "$RESET"