I wrote the following function in ksh that prints its first argument to the screen and underlines it with the appropriate ammount of - character:print_underlined () {    word=$1     echo $word    i=${#word}    while [[ i -gt 0 ]]; do        printf -        (( i = $i - 1 ))    done    printf \n}example:$ print_underlined foobarfoobar------$I wonder if there is a simpler and more elegant way to display an underlined word to the screen.For the record I am using:Solaris 10ksh88
Formatting the output: Underlining
shell;solaris;ksh
The core of your question is building a string consisting entirely of underscores that is of the same length as an existing string. In recent enough versions of bash, ksh or zsh you can build this string with the ${VARIABLE//PATTERN/REPLACEMENT} construct: underlines=${word//?/_}. But this construct doesn't exist in ksh88.In any shell, you can use tr instead. POSIX-compliant implementations of tr let you write this:underlines=$(printf %s $word | tr -c '_' '[_*]')I think Solaris 10 has a POSIX-compliant tr by default, but there might be a historical implementation (compatible with earlier Solaris releases).Historical implementations of tr might not understand the [x*] syntax, but they tend to accept the following syntax instead (which isn't guaranteed by POSIX), to mean replace everything that isn't a newline by a _:underlines=$(echo $word | tr -c '\010' '_')underlines=${underlines%_}And here's a slightly crazy method that doesn't use any loop or external program and should work in any Bourne shell (at least since set -f was introduced  though running in an empty directory would mitigate the lack of set -f). Unfortunately, it only works if the string doesn't contain any whitespace.set -f          # turn off globbingIFS=$word       # split at any character in $wordset a $word     # split $word into one word between each character, i.e. empty wordsshift           # remove the leading a (needed in case $word starts with -)IFS=_underlines=$*   # join the empty words, separated with the new value of $IFSA more complex variant deals with whitespace, but only if there isn't any consecutive whitespace sequence. I don't think you can go any further with this trick, since sequences of whitespace characters in IFS are always collapsed.set -funset IFS; set a $0    # split at whitespaceIFS=$*; set $*         # split into empty wordsIFS=_; underlines=$*   # collect the empty