Skip to content

Instantly share code, notes, and snippets.

@TrinityCoder
Last active August 8, 2024 17:55
Show Gist options
  • Save TrinityCoder/911059c83e5f7a351b785921cf7ecdaa to your computer and use it in GitHub Desktop.
Save TrinityCoder/911059c83e5f7a351b785921cf7ecdaa to your computer and use it in GitHub Desktop.
How to center text in Bash

Sometimes we might want to print some text in Bash and we might want it to be centered to the centre of the terminal. It is a cheap way how we can increase clarity of output of our script and make it look much more attractive.

The whole magic is hidden in a program called tput.

To get number of rows and cols of current terminal, we need just two simple shell substitutions:

    TERM_ROWS="$(tput rows)"
    TERM_COLS="$(tput cols)"

For centering our arbitrary text to the middle of the terminal, we actually only need to know the value of TERM_COLS. So we are already ready to go!

How to do it

Without further comments, I present here a simple bash function called print_centered, which awaits one or two arguments. The first argument is a string to be centered, the second argument is a character that should fill the rest of the line.

Default filling character is -

function print_centered {
     [[ $# == 0 ]] && return 1

     declare -i TERM_COLS="$(tput cols)"
     declare -i str_len="${#1}"
     [[ $str_len -ge $TERM_COLS ]] && {
          echo "$1";
          return 0;
     }

     declare -i filler_len="$(( (TERM_COLS - str_len) / 2 ))"
     [[ $# -ge 2 ]] && ch="${2:0:1}" || ch=" "
     filler=""
     for (( i = 0; i < filler_len; i++ )); do
          filler="${filler}${ch}"
     done

     printf "%s%s%s" "$filler" "$1" "$filler"
     [[ $(( (TERM_COLS - str_len) % 2 )) -ne 0 ]] && printf "%s" "${ch}"
     printf "\n"

     return 0
}

And this is how it can look in real usage:

------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
                 Building local Jekyll project in: /home/user/jekyll/example.com                 
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
Configuration file: /home/user/jekyll/example.com/_config.yml
            Source: /home/user/jekyll/example.com
       Destination: /home/user/jekyll/example.com/_site
 Incremental build: disabled. Enable with --incremental
      Generating... 
                    done in 0.21 seconds.
 Auto-regeneration: disabled. Use --watch to enable.

The first five lines are printed by print_centered function. The first two and last two are printed using command

print_centered "-" "-"

which centers one - at the middle of the terminal and fills the rest of line with the same character - an easy way to achieve a "horizontal bar".

If you have any questions about this, feel free to ask in comments.

@Timmiej93
Copy link

Ah, that's clever, I didn't do that. I noticed that pre- and postfix things didn't get taken into account for the length of the output, but I didn't think to use it for colors. I kinda want to have my text in a different color than the fillers and surrounding characters though, so that wouldn't really help me.

@n0ct
Copy link

n0ct commented Apr 18, 2024

Hmm indeed I did not undertook that use case in the script.
You could try to modify it by yourself but if you really don't manage to do so ping me again here and, if I have a bit time, I will try to do so ^^

@Timmiej93
Copy link

No worries, it's not that critical. If you ever get around to it though, I think it'd be a nice addition. You should probably put it in its own gist, it's a bit hidden in the comments now, despite being extremely useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment