348

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.

psmears
  • 26,070
  • 4
  • 40
  • 48
JamesRat
  • 3,640
  • 2
  • 16
  • 15

4 Answers4

577

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
  • 71,951
  • 46
  • 188
  • 305
psmears
  • 26,070
  • 4
  • 40
  • 48
  • 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
  • 8
    `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
  • I tried to use it and on commandline this works. But when I try to write the echo-ed command output to output.txt file then it does not write character in bolds. Any suggestions on how I can print output in bold in side .txt file – Nin Dec 23 '22 at 07:43
  • @Nin: How are you displaying the text file? If you're using `cat` you should see the bold text. If you're using `less` you'll need to use `less -R` to see the bold effect. – psmears Dec 23 '22 at 08:07
  • I @psmears, I found via hard way that .txt file extension perhaps doesn't support showing output in bold irrespective if I use cat or any other command. Tried to vi the .txt file and saw it doesn't show output in bold or any other style in .txt file. Thanks for offering help though – Nin Dec 23 '22 at 10:12
  • @Nin: Text files _can_ contain the control codes, but it depends what program you use to display the file whether the text will display as bold. If you use `cat` it will work. With `vi` or `vim` it will not work. With `less` it will only work if you specify the right option. – psmears Dec 23 '22 at 16:23
  • if you have a bash script you can define `bold() { echo -e "\033[1m$1\033[0m"; }` and then call it via `bold foo bar` which will print **foo bar** – Heinrich Apr 06 '23 at 15:25
  • @Heinrich: You'd want to do something like `echo "${bold}$1${normal}"` to retain the advantage of `tput`, namely that it can cope with different types of terminal. – psmears Apr 06 '23 at 15:53
  • @psmears my suggestion doesn't require `tput`, its more just referring about a general quick function you can define a bash script and then continuously call – Heinrich May 04 '23 at 15:49
  • @Heinrich: It will require `tput` _if you want it to work on different types of terminal_ - that's why this answer recommends using `tput`, because it will still work even if you have an obscure terminal with different control codes (or, probably more likely these days, the user has set up their environment so that "bold" displays on their screen in a way that they find more useful than the default). – psmears May 04 '23 at 15:54
199

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
  • 12,197
  • 3
  • 67
  • 61
54

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
  • 11,526
  • 3
  • 30
  • 42
  • 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
  • 3
    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
23

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
  • 18,187
  • 7
  • 57
  • 86