Assuming you are using the bash
shell (see the end of this answer if not using bash
), you can strip flanking whitespace from the string in str
more efficiently using standard variable expansions and the extended globbing pattern +([[:space:]])
(matches one or more space-like characters):
shopt -s extglob
str=$1
str=${str##+([[:space:]])} # strip at start
str=${str%%+([[:space:]])} # strip at end
We would want to print the string right-justified to the column given by (w+s)/2, where w is the width of the terminal (outputted by tput cols
, but you may also use $COLUMNS
) and s is the length of the string (${#str}
):
printf '%*s\n' "$(( ( $(tput cols) + ${#str} ) / 2 ))" "$str"
The function:
center () (
shopt -s extglob
str=$1
str=${str##+([[:space:]])}
str=${str%%+([[:space:]])}
printf '%*s\n' "$(( ( $(tput cols) + ${#str} ) / 2 ))" "$str"
)
Note that the body of the function is a sub-shell. This is so that the setting of the extglob
shell option does not spill over into the calling shell.
Without relying on extglob
(will work in any sh
):
center () {
str=$(printf '%s\n' "$1" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
printf '%*s\n' "$(( ( $(tput cols) + ${#str} ) / 2 ))" "$str"
}
Replace $(tput cols)
with 80
if you want to format this to a static 80-column width.
vim
is an option, it's just:center
there (based on thetextwidth
akatw
setting). – Stéphane Chazelas Dec 24 '22 at 08:22bash
answers were suggested as this is the most common shell in use, and you did not specify a particular shell in the question. Note also that my own answer did already have ash
-only part to it, which I hope I have now pointed out a bit more explicitly. – Kusalananda Dec 24 '22 at 09:42