How to right-align text in your bash prompt
Right aligning text by padding with spaces
To have text in your bash prompt ($PS1
) hug the right side of the terminal:
PS1="`printf "%${COLUMNS}s\n" "${TEXT}"`$PS1"
(This assumes you want the right-aligned text to appear before the rest of your prompt, if any. Move the $PS1
bit to the left side of the string to have the right-aligned text appear after the rest of your prompt.)
The ${COLUMNS}
variable contains the number of columns in the current terminal (it should change if you resize the terminal). The ${TEXT}
variable is a placeholder for the text you want to right-align.
The trick here is to use printf
to left-pad the string to given width. printf "%ns" "text"
will left-pad the given string (here, text
) with spaces until the entire string is n characters wide.
Right aligning text by padding with something other than space.
Say you want to pad with -
instead of space. Try:
PS1="`printf -vch "%${COLUMNS}s" "${TEXT}"; printf "%s" "${ch// /-}"`$PS1"
This will left-pad the ${TEXT}
with spaces, as above, and then replace any spaces with -
.
If you have any spaces in ${TEXT}
you want to preserve, one hacky work-around is to mark spaces in $TEXT
with some other character, say _
, and then replace _
with a space () after the other substitution:
$ PS1="$PS1`printf -vch "%${COLUMNS}s" "${TEXT}"; printf -vch "%s" "${ch// /-}"; printf "%s\n" "${ch//_/ }"`"
Drawing a line to the end of the line
I recently added a line containing the date and time to my bash prompt (so I can tell when a given command completed) and wanted to draw a line across the rest of the screen to make it visually easier to tell where a new prompt is displayed. Something like this:
-- Tue 02-Oct-2012 05:19 PM --------------------------------
(Assuming the terminal is 60 characters wide.)
Here's how I did it.
Within my $PROMPT_COMMAND
I execute the following:
line="`printf -vch "%${COLUMNS}s" ""; printf "%s" "${ch// /-}"`"
dts="`date +"-- %a %d-%b-%Y %I:%M %p "`"
PS1="$PS1\e[1m\e[32m${dts}${line:${#dts}}"
The first line creates a variable ($line
) with ${COLUMNS}
dashes (-
). This line would span the length of the terminal.
The second line creates a variable ($dts
) with my date and time format of choice (prefixed with --
just for kicks).
The ${dts}${line:${#dts}}
bit in the third line displays my date and time string ($dts
) and then a substring of $line
, starting at the length of my date and time string (${#dts}
). (In this particular case ${dts}
is always exactly 28 characters long, so that value could be hard-coded but this way it works in the general case too.)
If you are curious, the \e[1m\e[32m
bit makes the text bold (\e[1m
) and green (\e[32m
).