313

I'm writing a Bash script that prints some text to the screen:

echo "Some Text"

Can I format the text? I would like to make it bold.

codeforester
  • 34,080
  • 14
  • 96
  • 122
JamesRat
  • 3,290
  • 2
  • 15
  • 15

5 Answers5

533

The most compatible way of doing this is using tput to discover the right sequences to send to the terminal:

bold=$(tput bold)
normal=$(tput sgr0)

then you can use the variables $bold and $normal to format things:

echo "this is ${bold}bold${normal} but this isn't"

gives

this is bold but this isn't

gsamaras
  • 69,751
  • 39
  • 173
  • 279
psmears
  • 23,925
  • 4
  • 38
  • 47
  • 3
    That's pretty nifty. If I understand correctly, This is the same as inserting the escapes, but it would work in other terminals (not VT100). – JamesRat May 27 '10 at 21:00
  • That's correct - it looks up the appropriate codes according to the value of TERM. – psmears May 27 '10 at 21:42
  • 3
    If you have the need to underline text, you could add a variable. Notice, the backticks are being removed from comment formatting. Use the same format in the answer. UNDERLINE=`tput smul` – jayem Aug 13 '13 at 17:51
  • 6
    `tput` is a great command with [lots of commands](http://stackoverflow.com/a/20983251/24874) for many different tasks. – Drew Noakes Jan 07 '14 at 22:28
  • I'm trying to something similar to what the OP is doing, but with a `motd` file. How/where would I define the `$bold` and `$normal` variables in that instance? – Matt Apr 25 '14 at 23:50
  • @Matt I don't think that's possible, I think you'd have to hard code the escape sequences (e.g. `\033[1m`; see Michal Trybus's answer) – Doktor J Feb 19 '18 at 02:36
  • This is brilliant, simple, and works like a charm. Thank you – Chris Scott Apr 02 '20 at 13:56
  • 1
    This tput command is much better than the escape characters. You do not need "-e" with echo and it works with the command read: ```read -p "this is ${bold}bold${normal} but this isn't"``` – Gael Jul 22 '20 at 03:44
  • It didn't work exactly as @psmears explained. I had to use: `echo $bold"bold text"$normal"normal text"`. Using zsh on CentOS 7. – Damon Hill Apr 10 '21 at 21:24
  • @DamonHill: The example works fine for me under zsh (CentOS 7). What problem were you experiencing? I wouldn't recommend putting the variables outside "" quotes, as you don't know what might be in them (eg if your script is running on some weird terminal where the control codes include a `*`, the shell will try to expand that as a glob and mess up the control sequence). – psmears Apr 10 '21 at 22:18
  • @psmears. when I used $(bold) the script showed errors like `/path/script: line 90: bold: command not found` – Damon Hill Apr 10 '21 at 22:22
  • 2
    @DamonHill: Ah OK - look closely, it's not `$(bold)` it's `${bold}`, i.e. curly brackets rather than round ones :) – psmears Apr 11 '21 at 21:03
  • Oh, you're right. The problem are the glasses, not the characters!! Sorry, and thank you for taking the time to help. – Damon Hill Apr 11 '21 at 21:22
  • 1
    you may want to protect it, e.g.: `bold=$(tput bold 2>/dev/null)` – Alex Cohn Nov 24 '21 at 21:00
144

In order to apply a style on your string, you can use a command like:

echo -e '\033[1mYOUR_STRING\033[0m'

Explanation:

  • echo -e - The -e option means that escaped (backslashed) strings will be interpreted
  • \033 - escaped sequence represents beginning/ending of the style
  • lowercase m - indicates the end of the sequence
  • 1 - Bold attribute (see below for more)
  • [0m - resets all attributes, colors, formatting, etc.

The possible integers are:

  • 0 - Normal Style
  • 1 - Bold
  • 2 - Dim
  • 3 - Italic
  • 4 - Underlined
  • 5 - Blinking
  • 7 - Reverse
  • 8 - Invisible
avivamg
  • 8,836
  • 1
  • 56
  • 40
50

I assume bash is running on a vt100-compatible terminal in which the user did not explicitly turn off the support for formatting.

First, turn on support for special characters in echo, using -e option. Later, use ansi escape sequence ESC[1m, like:

echo -e "\033[1mSome Text"

More on ansi escape sequences for example here: ascii-table.com/ansi-escape-sequences-vt-100.php

Michał Trybus
  • 10,996
  • 3
  • 27
  • 41
  • Thanks. I found some other lists of escape sequences, but the one you linked to is very extensive! – JamesRat May 27 '10 at 20:46
  • 20
    Don't forget to stop bold formatting at the end of the string: `echo -e "\033[1mSome Text\033[0m"` else the following lines of your terminal will be in bold too – mems Oct 08 '14 at 16:29
  • This solution works even with PHP-CLI, that's an advantage against other solution. – David Jan 02 '18 at 09:55
  • 1
    if you have trouble remembering `\033` you can use `\e` like `echo -e "\e[1msome text\e[0m"` – Felipe Alvarez Aug 30 '18 at 02:41
  • Also note that octal litteral are forbidden in JS so we have to replace the `\033` part by `\x1b` – TOPKAT Sep 06 '19 at 09:18
  • 1
    The octal escape sequence is allowed in JS (JavaScript) – user Oct 02 '19 at 16:58
19

In theory like so:

# BOLD
$ echo -e "\033[1mThis is a BOLD line\033[0m"
This is a BOLD line

# Using tput
tput bold 
echo "This" #BOLD
tput sgr0 #Reset text attributes to normal without clear.
echo "This" #NORMAL

# UNDERLINE
$ echo -e "\033[4mThis is a underlined line.\033[0m"
This is a underlined line. 

But in practice it may be interpreted as "high intensity" color instead.

(source: http://unstableme.blogspot.com/2008/01/ansi-escape-sequences-for-writing-text.html)

roufamatic
  • 17,737
  • 7
  • 54
  • 84
-3

This is an old post but regardless, you can also get boldface and italic characters by leveraging utf-32. There are even greek and math symbols that can be used as well as the roman alphabet.

Jamie Le Tual
  • 101
  • 1
  • 5