1

I have a simple minimum width format using printf like so

$ printf "[%-15s][%-10s][%-5s][%-10s]\n" "Hello" "World" "Eat" "Cake"
[Hello          ][World     ][Eat  ][Cake      ]

But when I try to add some color to it as per the instructions from here, the minimum width formatting goes away

$ GREEN=$(tput setaf 2) && printf "[%-15s][%-10s][%-5s][%-10s]\n" "Hello" "World" "Eat" "${GREEN}Cake"
[Hello          ][World     ][Eat  ][Cake]

Obviously you can't see on here that it's green, but you can see that the minimum width on the word 'Cake' has dissappeared. What you can't see, but which is also happening, is that the font of the word 'Cake' has changed as well.

Question: How can I change the color but keep the minimum width, and if possible, keep the font the same?

2 Answers2

1

It would appear that the printf function is counting the escape sequence characters that set the colours as part of the output width. Adding the number of characters required for each colour format to the width specifier should fix the issue.

Minimal Working Example:

$ GREEN=$(tput setaf 2) && printf "[%-15s][%-10s][%-5s][${GREEN}%-10s]\n" "Hello" "World" "Eat" "Cake"
[Hello          ][World     ][Eat  ][Cake      ]
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
1

This...

printf "[\x1b[34;1m%-15s\x1b[0m][\e[33;1m%-10s\e[0m][\e[31;5m%-5s\e[0m][\e[32m%-10s\e[0m]\n" "Hello" "World" "Eat" "Cake"

...works in my bash.

For better handling create a 4 columns format environment variable first for later use...

FRMT_BYRG_4COLS='[\x1b[34;1m%-15s\x1b[0m][\e[33;1m%-10s\e[0m][\e[31;5m%-5s\e[0m][\e[32m%-10s\e[0m]\n'

...and use it with all what puts out with 4 columns...

printf "${FRMT_BYRG_4COLS}" $(ps)

( printf loops through $(ps) 4 columns output )

koyaanisqatsi
  • 2,585
  • 2
  • 8
  • 15