23

Is it possible to change the font attributes of the output of echo in either zsh or bash?

What I would like is something akin to:

echo -n "This is the font: normal "
echo -n $font=italic "italic,"
echo -n $font=bold "bold,"
echo -n "and"
echo -n $font=small "small".

so that it print: "This is the font: normal, italic, bold, small" within a line of text.

2

5 Answers 5

24

On most if not all terminal emulators, you can't set different font sizes or different fonts, only colors and a few attributes (bold, underlined, standout).

In bash (or in zsh or any other shell), you can use the terminal escape sequences directly (apart from a few exotic ones, all terminals follow xterm's lead these days). CSI is ESC [, written $'\e[' in bash. The escape sequence to change attributes is CSI Ps m.

echo $'\e[32;1mbold red\e[0mplain\e[4munderlined'

Zsh has a convenient function for that.

autoload -U colors
colors
echo $bold_color$fg[red]bold red${reset_color}plain$'\e['$color[underline]munderlined

Or can do it as part of prompt expansion, also done with print -P, or the % parameter expansion flag:

print -P '%F{red}%Bbold%b red%f %Uunderline%u'
2
  • With the convenient zsh I get bold redplain4munderlined where bold red is bold and red with zsh 5.8.
    – Timo
    Jun 16, 2021 at 19:14
  • 1
    @Timo Thanks for the bug report. A bracket was missing, I've added it. Jun 16, 2021 at 19:36
20

You could include these color definitions in a script or source file. Could look something like this.

#!/bin/bash
PATH=/bin:/usr/bin:

NONE='\033[00m'
RED='\033[01;31m'
GREEN='\033[01;32m'
YELLOW='\033[01;33m'
PURPLE='\033[01;35m'
CYAN='\033[01;36m'
WHITE='\033[01;37m'
BOLD='\033[1m'
UNDERLINE='\033[4m'

echo -e "This text is ${RED}red${NONE} and ${GREEN}green${NONE} and ${BOLD}bold${NONE} and ${UNDERLINE}underlined${NONE}."

tput sgr0

Notice that you should reset the ANSI color codes after each instance you invoke a change. The tput sgr0 resets all changes you have made in the terminal.

I believe changing the font size or italics would be specific to the terminal you are using.

While this guide is specific to customizing your bash prompt, it is a good reference for color codes and generates some ideas of what you can do.

0
8

Seems as if the layout can't handle the [0x1b]-character in front of the [.

The first line makes bold:

 echo -e "\x1b[1m bold"
     echo -e "\x1b[30m black"
     echo -e "\x1b[31m red"
     echo -e "\x1b[32m green"
     echo -e "\x1b[33m yellow"
     echo -e "\x1b[34m blue"
     echo -e "\x1b[35m mag"
     echo -e "\x1b[36m cyan"
     echo -e "\x1b[37m white"   

For the general type, I only know

echo -e "\x1b[0m io-std"
echo -e "\x1b[1m bold"
echo -e "\x1b[2m normal"

and from the comments, thanks manatwork and GypsyCosmonaut:

echo -e "\x1b[3m italic"
echo -e "\x1b[4m underlined"
echo -e "\x1b[5m blinking"
echo -e "\x1b[7m inverted"

and don't know the difference between io-std and normal.

I haven't seen italic or small in the shell.

You can enter them (thanks to manatwork too) by Ctrl + v ESC in the Bash, where it will be displayed as ^[. This mean the whole ANSI sequence will look like ^[[1m bold or ^[[1mbold (to avoid the blank before 'bold').

Many editors have problems with (char)0x1b. Alternatives: copy/paste it from somewhere, or use

echo -e "\x1b[1m bold"

in bash, or a hex editor.

Or, even simpler:

echo -e "\e[1m bold"

The \e is an escape sequence for the ascii code 27, for the bash internal command echo as well as for the external program GNU-echo.

4
  • 1
    Escape characters can be typed: Ctrl+V, Esc. (Will be displayed as “^[”. This mean the whole ANSI sequence will look like “^[[1mbold”.)
    – manatwork
    Apr 25, 2012 at 11:49
  • 1
    There are more attributes to mention: \e[4m underlined, \e[5m blinking, \e[7m inverted.
    – manatwork
    Apr 25, 2012 at 11:52
  • @manatwork: added them. Apr 25, 2012 at 12:04
  • @userunknown Thanks for helping, tinkering with your code, I found italic is echo -e "\x1b[3m italic" Jul 16, 2017 at 11:13
2

Note that for letters in the latin script specifically (there are also options for letters in other scripts, but more limited), Unicode has mathematical characters with various rendering attributes. For instance, for a/A, there's:

U+1D400 MATHEMATICAL BOLD CAPITAL A
U+1D41A MATHEMATICAL BOLD SMALL A
U+1D434 MATHEMATICAL ITALIC CAPITAL A
U+1D44E MATHEMATICAL ITALIC SMALL A
U+1D468 MATHEMATICAL BOLD ITALIC CAPITAL A
U+1D482 MATHEMATICAL BOLD ITALIC SMALL A
U+1D49C MATHEMATICAL SCRIPT CAPITAL A
U+1D4B6 MATHEMATICAL SCRIPT SMALL A
U+1D4D0 MATHEMATICAL BOLD SCRIPT CAPITAL A
U+1D4EA MATHEMATICAL BOLD SCRIPT SMALL A
U+1D504 MATHEMATICAL FRAKTUR CAPITAL A
U+1D51E MATHEMATICAL FRAKTUR SMALL A
U+1D538 MATHEMATICAL DOUBLE-STRUCK CAPITAL A
U+1D552 MATHEMATICAL DOUBLE-STRUCK SMALL A
U+1D56C MATHEMATICAL BOLD FRAKTUR CAPITAL A
U+1D586 MATHEMATICAL BOLD FRAKTUR SMALL A
U+1D5A0 MATHEMATICAL SANS-SERIF CAPITAL A
U+1D5BA MATHEMATICAL SANS-SERIF SMALL A
U+1D5D4 MATHEMATICAL SANS-SERIF BOLD CAPITAL A
U+1D5EE MATHEMATICAL SANS-SERIF BOLD SMALL A
U+1D608 MATHEMATICAL SANS-SERIF ITALIC CAPITAL A
U+1D622 MATHEMATICAL SANS-SERIF ITALIC SMALL A
U+1D63C MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A
U+1D656 MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A
U+1D670 MATHEMATICAL MONOSPACE CAPITAL A
U+1D68A MATHEMATICAL MONOSPACE SMALL A

So, if you can't use graphic rendering escape sequences because for instance it's to be displayed on something other than a terminal, you could use those.

italic() {
  sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻/'
}
$ echo Hellow World | italic
𝘏𝘦𝘭𝘭𝘰𝘸 𝘞𝘰𝘳𝘭𝘥
0

Here:

http://en.wikipedia.org/wiki/ANSI_escape_code

(note: a lot of them usually don't work, but most of these are marked thus.)

I'm making a game in the terminal and have been relying heavily on the above link. It even tells you how to hide/unhide the cursor, make color (30's), "bold" (lighter), darker, underlined, italic, background color (40's instead of 30's), etc. You can also change the cursor's location (which is very helpful - for example, "\x1B[1A" moves the cursor up one line; "\x1B[0;0H" moves the cursor to row 0, col 0; "\x1B[2J" clears the screen; "\x1B[2K" clears the line.

For your purposes as people have said:

echo -e "\x1b[30;44m black with blue background \x1b[m"
echo -e "\x1b[31;42m red with green background \x1b[m"
echo -e "\x1b[32;40m green with black background \x1b[m"
echo -e "\x1b[8m Invisible; na na na na boo boo \x1b[m"

Note: You need the -e in:

echo -e "\x1b[35;1m Light purple \x1b[m"

or you need to use single quotes. Type man echo to see why (double quotes are usually a pain when printing; when I need stuff to not expand or I need ANSI escape sequences, I use single quotes because it is easy - even though I gotten used to it from doing it so many times - to forget the -e in which case you get "box with numbers and letters[35;1m").

Every time you see CSI replace it with "\x1b[" (or "\e[" or "\u1b["). "\x1b[" I think is more standard, but I don't really know what the difference is between them is.

3
  • If you like cluttering your strings with extra characters, don't use \e :-)
    – clearlight
    Jan 15, 2017 at 21:01
  • @clearlight I am not sure what you mean. I think you might have meant to say "use \e". However, \e is less supported than \x1b I have found. The optimal thing to do would be either esc=$'\e' or esc=$'\x1b' (this is in bash) and then use "${esc}[34;1m" (for, e.g., bright blue). I have a semi-complex example here (github.com/dylnmc/ps1porn/blob/master/powerline.sh) for a real bash prompt string ;) Please forgive the name of the repo -- you can thank people in freenode's channel #archlinux-offtopic for that.
    – Dylan
    Feb 3, 2017 at 17:37
  • Reason for doing esc=$'\e' is that this allows bash to create the ansi-escape character on the spot, and you benefit from it in a couple of ways. Sometimes, in fact, (as is demonstrated in the github link), you have to use this method in order to get color to show up properly. For older versions of bash as well as the sh shell, you should (but don't need to) use this method to get color to show up ... granted that the terminal uses the escape sequences that most modern terminals do.
    – Dylan
    Feb 3, 2017 at 18:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .