22

I've been trawling the web trying to find examples of Unix Bash script that can handle basic text styling (bold/underline/italics), but can't find anything? Is such a thing possible to do?

For example:

  1. Embolden/Underline/Italicize all lines ending in ":"?
  2. (Turn off) Embolden/Underline/Italicize all lines ending in ":"?

I want to set it up as a Service via Automator; so using /bin/bash and actioning on "selected text" (in a rich-text-compatible file, of course).

John Kugelman
  • 349,597
  • 67
  • 533
  • 578

2 Answers2

22

Basically, you want to do declare some variables with the styling code--something like this:

underline=`tput smul`
nounderline=`tput rmul`
bold=`tput bold`
normal=`tput sgr0`

then you can call these for use in your output using the variables, like this:

echo "${bold}bold${normal} text stands out!"
echo "${underline}underlined${nounderline} text does, too."

As far as automating it to apply to all lines beginning with a specific character, you're better off just using the variables as shown above. Besides using this method just being easier, it's also cleaner and more usable. For example, when using this method you have the ability to style any number of words in a given output string differently, so as to emphasize a specific word, not the entire sentence (unless of course that's your goal).

For more information, you should check out http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x405.html and/or man tput

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
Chris Cashwell
  • 22,308
  • 13
  • 63
  • 94
  • Also, it should be noted that although **tput sgr0** does remove ALL styling, it doesn't always perform as expected, so it's best to use the "exit" code related to the styling you're using (i.e. using ${underline} to start the underlining area, then calling ${nounderline} to end the style usage). – Chris Cashwell Dec 11 '10 at 00:11
  • Cheers, Chris. I'm new to Unix Bash and only really familiar with the "one-liner" approach, so excuse my ignorance, but can the code you provided (with variables, etc) be used in Automator bin/bash? I also don't understand the use of "echo", "$"... I've only ever seen echo used in PHP. –  Dec 11 '10 at 00:32
  • Can you show an example of `sgr0` not performing as expected? – Dennis Williamson Dec 11 '10 at 01:28
  • bolded= \`tput bold\` While defining, it mention the variable is "bolded" but in echo (see below) it is written "bold" therefore it doesn't perform the required operation. You can correct it by making both similar. echo "${bold}bold${normal} text stands out!" –  Sep 19 '11 at 21:53
  • @DennisWilliamson: `sgr0` will completely remove all styles, not just the last used style. So, for instance, if you were trying to underline the entire string, while only bolding a single word in the beginning by doing `${underline}${bold}this${normal} is important${nounderline}`, `${normal}` drops the underline after that definition also. If you're not familiar with `sgr0`, this could be confusing, hence unexpected behavior. Styles can be nested, so the proper way to execute the example here would be `${underline}${bold}this${normal}${underline} whole line is important${nounderline}`. – Chris Cashwell Sep 21 '11 at 16:42
  • Is there any reason that you wouldn't use `underline='\033[4m'` and `normal='\033[0m'`, etc? – Mike Apr 09 '15 at 14:30
0

Just to add, that instead of using tput, you can also specify colors as ANSI escape sequences.

These are specified like \033[XXXm, where XXX is a series of semicolon-separated parameters (as covered by the ECMA-48 standard). For example:

Color_Off='\033[0m'       # Text Reset

# Regular Colors
Black='\033[0;30m'        # Black
Red='\033[0;31m'          # Red
Green='\033[0;32m'        # Green
Yellow='\033[0;33m'       # Yellow
Blue='\033[0;34m'         # Blue
Purple='\033[0;35m'       # Purple
Cyan='\033[0;36m'         # Cyan
White='\033[0;37m'        # White

# Bold
BBlack='\033[1;30m'       # Black
BRed='\033[1;31m'         # Red
BGreen='\033[1;32m'       # Green
BYellow='\033[1;33m'      # Yellow
BBlue='\033[1;34m'        # Blue
BPurple='\033[1;35m'      # Purple
BCyan='\033[1;36m'        # Cyan
BWhite='\033[1;37m'       # White

# Underline
UBlack='\033[4;30m'       # Black
URed='\033[4;31m'         # Red
UGreen='\033[4;32m'       # Green
UYellow='\033[4;33m'      # Yellow
UBlue='\033[4;34m'        # Blue
UPurple='\033[4;35m'      # Purple
UCyan='\033[4;36m'        # Cyan
UWhite='\033[4;37m'       # White

# Background
On_Black='\033[40m'       # Black
On_Red='\033[41m'         # Red
On_Green='\033[42m'       # Green
On_Yellow='\033[43m'      # Yellow
On_Blue='\033[44m'        # Blue
On_Purple='\033[45m'      # Purple
On_Cyan='\033[46m'        # Cyan
On_White='\033[47m'       # White

# High Intensity
IBlack='\033[0;90m'       # Black
IRed='\033[0;91m'         # Red
IGreen='\033[0;92m'       # Green
IYellow='\033[0;93m'      # Yellow
IBlue='\033[0;94m'        # Blue
IPurple='\033[0;95m'      # Purple
ICyan='\033[0;96m'        # Cyan
IWhite='\033[0;97m'       # White

# Bold High Intensity
BIBlack='\033[1;90m'      # Black
BIRed='\033[1;91m'        # Red
BIGreen='\033[1;92m'      # Green
BIYellow='\033[1;93m'     # Yellow
BIBlue='\033[1;94m'       # Blue
BIPurple='\033[1;95m'     # Purple
BICyan='\033[1;96m'       # Cyan
BIWhite='\033[1;97m'      # White

# High Intensity backgrounds
On_IBlack='\033[0;100m'   # Black
On_IRed='\033[0;101m'     # Red
On_IGreen='\033[0;102m'   # Green
On_IYellow='\033[0;103m'  # Yellow
On_IBlue='\033[0;104m'    # Blue
On_IPurple='\033[0;105m'  # Purple
On_ICyan='\033[0;106m'    # Cyan
On_IWhite='\033[0;107m'   # White

E.g. to print in bright purple (note that -e is required to enable interpretation of backslash escapes)

echo -e "\033[0;95m Hello World!\033[0m"

Colors are rendered by the terminal you are using, traditionally terminal colors were 8-bit, nowadays most termainl emulators are true color / 256-bit.

Alicia Sykes
  • 5,997
  • 7
  • 36
  • 64