mpapec
mpapec

Reputation: 50657

psql displaying ansi colored text

My .psqlrc has following options

\setenv LESS '-iMSx4 -FXR'
\setenv PAGER 'less'
\pset pager always

and psql output which I want to be colored is

 {                                                                    +
    \x1B[35m"\x1B[0m\x1B[35mr\x1B[0m\x1B[35m"\x1B[0m: [               +
       \x1B[1m\x1B[92m"\x1B[0m\x1B[32m1\x1B[0m\x1B[1m\x1B[92m"\x1B[0m,+
       \x1B[1m\x1B[92m"\x1B[0m\x1B[32m2\x1B[0m\x1B[1m\x1B[92m"\x1B[0m,+
       \x1B[1m\x1B[92m"\x1B[0m\x1B[32m3\x1B[0m\x1B[1m\x1B[92m"\x1B[0m,+
       \x1B[1m\x1B[92m"\x1B[0m\x1B[32m4\x1B[0m\x1B[1m\x1B[92m"\x1B[0m,+
       \x1B[1m\x1B[92m"\x1B[0m\x1B[32m5\x1B[0m\x1B[1m\x1B[92m"\x1B[0m,+
       \x1B[1m\x1B[92m"\x1B[0m\x1B[32m6\x1B[0m\x1B[1m\x1B[92m"\x1B[0m,+
       \x1B[1m\x1B[92m"\x1B[0m\x1B[32m7\x1B[0m\x1B[1m\x1B[92m"\x1B[0m,+
       \x1B[1m\x1B[92m"\x1B[0m\x1B[32m8\x1B[0m\x1B[1m\x1B[92m"\x1B[0m +
    ]                                                                 +
 }

Is there a way to make pager aware of \x1B ansi sequences, or to tell psql not to convert them to hexadecimal representations when displaying?

Output should look like,

enter image description here

Upvotes: 4

Views: 1590

Answers (2)

Vainstein K
Vainstein K

Reputation: 202

An "all-in-one" psql solution:

\o | sed -r 's/\\x1B\[([0-9]+)m/\x1B[\1m/g' | less -R

That's it --- no other psql or shell commands required.

How It Works

  • \o     <===   Gives us direct control of stdout.
  • | sed -r 's/\\x1B\[([0-9]+)m/\x1B[\1m/g'     <===   We re-print all the escape sequences exactly as they were, but now interpreted as themselves and not as literals.
  • | less -R     <===   We hand the result over to less(1) explicitly (psql isn't going to do it for us, because we took over control of stdout!). The options to be given to less(1) are up to you; as long as they include -R (or -r), colorization will happen.

Works for output of both SELECTs and of \echo meta-commands.

Upvotes: 3

Thomas Dickey
Thomas Dickey

Reputation: 54563

The less pager can be told to filter its input files using the LESSOPEN environment variable.

For your case, that could be the name of a script which changes all of \x1B to the ASCII escape character, e.g.,

sed -e 's/\x1B/^[/'

(where the ^[ is a literal control[ character: using controlV when inserting with a text editor helps).

Further reading:

Per comment: if psql calls the pager via a pipe, bypassing LESSOPEN (which works given a file), you should set your pager to a script which does the combination of filtering and paging, e.g., a script something like

#!/bin/sh
perl -pe "s|\\\(x..)|chr(hex(\$1))|ge" | less -iMSx4 -FXR

since perl works from a pipe if no filenames are given.

EDIT:

Solution without external script using psql only,

\setenv LESS '-iMSx4 -FXR'
\setenv PAGER 'perl -pe \'s|\\\\(x..)|chr(hex($1))|ge\' | less'

Upvotes: 3

Related Questions